Identify it then Move It (Macro) - vba

I had this project in Chemistry to supply a list of Compound elements
now I had found a website where it gives me a very long list of elements:
I had made this Code but it Doesn't Work
Sub move()
Dim list As Range
Set list = Range("A1:A2651")
For Each Row In list.Rows
If (Row.Font.Regular) Then
Row.Cells(1).Offset(-2, 1) = Row.Cells(1)
End If
Next Row
End Sub
Can you make it run for me? you can have your own algorithm ofc.

Assuming the list is constantly in the same format (i.e. Compound name, empty line, Compound Symbols, empty line) this quick code will work:
Sub move()
Dim x As Integer
x = 3
With ActiveSheet
Do Until x > 2651
.Cells(x - 2, 2).Value = .Cells(x, 1).Value
.Cells(x, 1).ClearContents
x = x + 4
Loop
End With
End Sub
After running you can then just sort columns A:B to remove the blanks.
After trying your original code I realised the problem was with the .regular property value. I've not seen .regular before, so swapped it to NOT .bold instead, and to ignore blank entries, then added the line for clearing the contents of the cell copied. This is most like the original code for reference:
Sub get_a_move_on()
Dim list As Range
Set list = ActiveSheet.Range("A1:A2561")
For Each Row In list.Rows
If Row.Font.Bold = False And Row.Value <> "" Then
Row.Cells(1).Offset(-2, 1) = Row.Cells(1)
Row.Cells(1).ClearContents
End If
Next Row
End Sub
P.S it's a list of compounds, not elements, there's only about 120 elements in the periodic table! ;)

Another way to retrieve the data you need via XHR and RegEx:
Sub GetChemicalCompoundsNames()
Dim sRespText As String
Dim aResult() As String
Dim i As Long
' retrieve HTML content
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "https://quizlet.com/18087424", False
.Send
sRespText = .responseText
End With
' regular expression for rows
With CreateObject("VBScript.RegExp")
.Global = True
.MultiLine = True
.IgnoreCase = True
.Pattern = "qWord[^>]*?>([\s\S]*?)<[\s\S]*?qDef[^>]*?>([\s\S]*?)<"
With .Execute(sRespText)
ReDim aResult(1 To .Count, 1 To 2)
For i = 1 To .Count
With .Item(i - 1)
aResult(i, 1) = .SubMatches(0)
aResult(i, 2) = .SubMatches(1)
End With
Next
End With
End With
' output to the 1st sheet
With Sheets(1)
.Cells.Delete
Output .Range("A1"), aResult
End With
End Sub
Sub Output(oDstRng As Range, aCells As Variant)
With oDstRng
.Parent.Select
With .Resize( _
UBound(aCells, 1) - LBound(aCells, 1) + 1, _
UBound(aCells, 2) - LBound(aCells, 2) + 1 _
)
.NumberFormat = "#"
.Value = aCells
.Columns.AutoFit
End With
End With
End Sub
Gives output (663 rows total):

Related

Insert space between text and number for cells within column

I've already written a code that inserts a space between text and numbers, separating 'unspaced' days and months from dates, and it works as it's supposed to.
The only problem is that I'm using an If then structure to determine which Regular Expressions pattern I should use.
If the first character of the date is a number, then knowing that it is in the 'DayMonth' sequence, I use this pattern: "(.*\d)(?! )(\D.*)". Otherwise, assuming that it isn't in the 'DayMonth' sequence but rather in the 'MonthDay' sequence, I use the other pattern: "(.*\D)(?! )(\d.*)".
Is there any way to use two patterns at once for the Regular Expressions object to scan through so that I can get rid of the If Then structure?
My code below:
Sub SpaceMonthDayIf()
Dim col As Range
Dim i As Long
Set col = Application.InputBox("Select Date Column", "Obtain Object Range", Type:=8)
With CreateObject("VBScript.RegExp")
For i = 1 To Cells(Rows.Count, col.Column).End(xlUp).Row
If IsNumeric(Left(Cells(i, col.Column).Value, 1)) Then
.Pattern = "(.*\d)(?! )(\D.*)"
Cells(i, col.Column) = .Replace(Cells(i, col.Column), "$1 $2")
Else
.Pattern = "(.*\D)(?! )(\d.*)"
Cells(i, col.Column) = .Replace(Cells(i, col.Column), "$1 $2")
End If
Next
End With
End Sub
For clarity, here's what happens when I run my code:
Try this code
Sub Test()
Dim a, i As Long
With Range("A2", Range("A" & Rows.Count).End(xlUp))
a = .Value
With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "(\d+)"
For i = 1 To UBound(a, 1)
a(i, 1) = Application.Trim(.Replace(a(i, 1), " $1 "))
Next i
End With
.Columns(2).Value = a
End With
End Sub
You can avoid that by inserting your space differently. Here is a Function written with early-binding, but you can change that to late-binding.
Match the junction between a letter and a number, then construct a string, inserting a space appropriately.
Option Explicit
Function InsertSpace(S As String) As String
Const sPat As String = "[a-z]\d|\d[a-z]"
Dim RE As RegExp, MC As MatchCollection
Set RE = New RegExp
With RE
.Global = False
.Pattern = sPat
.IgnoreCase = True
If .Test(S) = True Then
Set MC = .Execute(S)
With MC(0)
InsertSpace = Left(S, .FirstIndex + 1) & " " & Mid(S, .FirstIndex + 2)
End With
End If
End With
End Function
You can also accomplish this without using Regular Expressions:
EDIT Pattern change for Like operator
Option Explicit
Option Compare Text
Function InsertSpace2(S As String) As String
Dim I As Long
For I = 1 To Len(S)
If Mid(S, I, 2) Like "#[a-z]" Or Mid(S, I, 2) Like "[a-z]#" Then
InsertSpace2 = Left(S, I) & " " & Mid(S, I + 1)
Exit Function
End If
Next I
End Function

Referencing Cells from Spreadsheet and Populating Corresponding Cells

Edit: More information - the objective of this program is to pull from an existing list of names, search the website, and bring back the corresponding NPI numbers. Thanks to user #omegastripes I was advised to shift my focus to XHR.
My question is regarding, how to populate the search with the names of the providers, and loop so that it will return the NPI's in the next cells over in the spread sheet for the remaining providers.
Related, what to do in the event nothing populates from the search
original post: Title - Do you want to continue? Internet Explorer pop up - VBA
Internet Security pop up prevents my code from continuing. Normally I would disable this request but my computer security access is limited due to using a work computer.
My question, is there a way to click "Yes" on this pop up using VBA?
Here is my code so far.
Sub GetNpi()
Dim ie As Object
'create a new instance of ie
Set ie = New InternetExplorer
ie.Visible = True
'goes to site
ie.navigate "npinumberlookup.org"
Do While ie.readyState <> READYSTATE_COMPLETE
Loop
Set ieDoc = ie.document
'select search box last name and Fill in Search Box
ie.document.getElementById("last").Focus
ie.document.getElementById("last").Value = "testlastname"
'select search box first name and Fill in Search Box
ie.document.getElementById("first").Focus
ie.document.getElementById("first").Value = "testfirstname"
Do While ie.readyState <> READYSTATE_COMPLETE
Loop
'select state drop down box enter TX
ie.document.getElementById("pracstate").Focus
ie.document.getElementById("pracstate").Value = "TX"
'click submit button
ie.document.getElementById("submit").Click
Update
Try the below code to retrieve NPI for the names from the worksheet (specify last name, first name and state):
Option Explicit
Sub TestListNPI()
' Prefix type + func
' Type: s - string, l - long, a - array
' Func: q - query, r - result
Dim i As Long
Dim j As Long
Dim k As Long
Dim sqLN As String
Dim sqFN As String
Dim aqFN
Dim sqSt As String
Dim arHdr
Dim arRows
Dim srMsg As String
Dim srLN As String
Dim srFN As String
Dim arFN
Dim lrMNQty As Long
Dim sOutput As String
i = 2
With Sheets(1)
Do
sqLN = .Cells(i, 1)
If sqLN = "" Then Exit Do
.Cells(i, 4) = "..."
sqFN = .Cells(i, 2).Value
aqFN = Split(sqFN)
sqSt = "" & .Cells(i, 3)
GetNPIData sqLN, aqFN(0), sqSt, arHdr, arRows, srMsg
If srMsg = "OK" Then
With CreateObject("Scripting.Dictionary")
For j = 0 To UBound(arRows, 1)
Do
srLN = arRows(j, 1)
If LCase(srLN) <> LCase(sqLN) Then Exit Do ' Last names should match
srFN = arRows(j, 3)
arFN = Split(srFN)
If LCase(arFN(0)) <> LCase(aqFN(0)) Then Exit Do ' First names should match
lrMNQty = UBound(arFN)
If UBound(aqFN) < lrMNQty Then lrMNQty = UBound(aqFN)
For k = 1 To lrMNQty
Select Case True
Case LCase(arFN(k)) = LCase(aqFN(k)) ' Full match
Case Len(arFN(k)) = 1 And LCase(arFN(k)) = LCase(Left(aqFN(k), 1)) ' First letter match
Case Len(arFN(k)) = 2 And Right(arFN(k), 1) = "." And LCase(Left(arFN(k), 1)) = LCase(Left(aqFN(k), 1)) ' First letter with dot match
Case Else ' No matches
Exit Do
End Select
Next
.Add arRows(j, 0), arRows(j, 1) & " " & arRows(j, 3)
Loop Until True
Next
Select Case .Count
Case 0
sOutput = "No matches"
Case 1
sOutput = .Keys()(0)
Case Else
sOutput = Join(.Items(), vbCrLf)
End Select
End With
Else
sOutput = srMsg
End If
.Cells(i, 4) = sOutput
DoEvents
i = i + 1
Loop
End With
MsgBox "Completed"
End Sub
Sub GetNPIData(sLastName, sFirstName, sState, aResultHeader, aResultRows, sStatus)
Dim sContent As String
Dim i As Long
Dim j As Long
Dim aHeader() As String
Dim aRows() As String
' Retrieve HTML content via XHR
With CreateObject("MSXML2.XMLHTTP")
.Open "POST", "http://npinumberlookup.org/getResults.php", False
.SetRequestHeader "content-type", "application/x-www-form-urlencoded"
.Send _
"last=" & EncodeUriComponent(sLastName) & _
"&first=" & EncodeUriComponent(sFirstName) & _
"&pracstate=" & EncodeUriComponent(sState) & _
"&npi=" & _
"&submit=Search" ' Setup request parameters
sContent = .ResponseText
End With
' Parse with RegEx
Do ' For break
With CreateObject("VBScript.RegExp")
.Global = True
.MultiLine = True
.IgnoreCase = True
' Minor HTML simplification
.Pattern = "<(?!/td|/tr|/th|td|tr|th|a href)[^>]*>| |\r|\n|\t"
sContent = .Replace(sContent, "")
.Pattern = "<a [^>]*href=""([^""]*)"".*?</td>"
sContent = .Replace(sContent, "$1</td>")
.Pattern = "<(\w+)\b[^>]+>"
sContent = .Replace(sContent, "<$1>")
' Extract header
.Pattern = "<tr>((?:<th>.*?</th>)+)</tr>"
With .Execute(sContent)
If .Count <> 1 Then
sStatus = "No header"
Exit Do
End If
End With
.Pattern = "<th>(.*?)</th>"
With .Execute(sContent)
ReDim aHeader(0, 0 To .Count - 1)
For i = 0 To .Count - 1
aHeader(0, i) = .Item(i).SubMatches(0)
Next
End With
aResultHeader = aHeader
' Extract data
.Pattern = "<tr>((?:<td>.*?</td>)+)</tr>"
With .Execute(sContent)
If .Count = 0 Then
sStatus = "No rows"
Exit Do
End If
ReDim aRows(0 To .Count - 1, 0)
For i = 0 To .Count - 1
aRows(i, 0) = .Item(i).SubMatches(0)
Next
End With
.Pattern = "<td>(.*?)</td>"
For i = 0 To UBound(aRows, 1)
With .Execute(aRows(i, 0))
For j = 0 To .Count - 1
If UBound(aRows, 2) < j Then ReDim Preserve aRows(UBound(aRows, 1), j)
aRows(i, j) = Trim(.Item(j).SubMatches(0))
Next
End With
Next
aResultRows = aRows
End With
sStatus = "OK"
Loop Until True
End Sub
Function EncodeUriComponent(sText)
Static oHtmlfile As Object
If oHtmlfile Is Nothing Then
Set oHtmlfile = CreateObject("htmlfile")
oHtmlfile.parentWindow.execScript "function encode(s) {return encodeURIComponent(s)}", "jscript"
End If
EncodeUriComponent = oHtmlfile.parentWindow.encode(sText)
End Function
The output for me is as follows:
For multiply entries all names are output in the last column instead of NPI.
Some explanation of the code. Generally RegEx's aren't recommended for HTML parsing, so there is disclaimer. Data being processed in this case is quite simple that is why it is parsed with RegEx. About RegEx: introduction (especially syntax), introduction JS, VB flavor. Simplification makes HTML code suitable for parsing in some degree. Patterns:
<(?!/td|/tr|/th|td|tr|th|a href)[^>]*>| |\r|\n|\t is for removing white-spaces, and all tags but table markup and links by replacing with "".
<a [^>]*href="([^"]*)".*?</td> keeps link address by replacing with $1</td>.
<(\w+)\b[^>]+> removes all unnecessary tag attributes by replacing with <$1>.
<tr>((?:<th>.*?</th>)+)</tr> matches each table header row.
<th>(.*?)</th> matches each header cell.
<tr>((?:<td>.*?</td>)+)</tr> matches each table data row.
<td>(.*?)</td> matches each data cell.
Look into how does the HTML content is changed on each step of replacemnets.
Initial answer
Avoid pop up appearing instead of bothering with it.
Make sure you are using secure HTTP protocol https://npinumberlookup.org.
You may even not use IE for webscraping at all, XHR is better choice, as it is more reliable and fast, though it requires some knowledge and experience. Here is the simple example of that:
Option Explicit
Sub Test()
Dim sContent As String
Dim i As Long
Dim j As Long
Dim aHeader() As String
Dim aRows() As String
' Retrieve HTML content via XHR
With CreateObject("MSXML2.XMLHTTP")
.Open "POST", "http://npinumberlookup.org/getResults.php", False
.SetRequestHeader "content-type", "application/x-www-form-urlencoded"
.Send _
"last=smith" & _
"&first=michael" & _
"&pracstate=NC" & _
"&npi=" & _
"&submit=Search" ' Setup request parameters
sContent = .ResponseText
End With
' Parse with RegEx
Do ' For break
With CreateObject("VBScript.RegExp")
.Global = True
.MultiLine = True
.IgnoreCase = True
' Minor HTML simplification
.Pattern = "<(?!/td|/tr|/th|td|tr|th|a href)[^>]*>| |\r|\n|\t"
sContent = .Replace(sContent, "")
.Pattern = "<a [^>]*href=""([^""]*)"".*?</td>"
sContent = .Replace(sContent, "$1</td>")
.Pattern = "<(\w+)\b[^>]+>"
sContent = .Replace(sContent, "<$1>")
' Extract header
.Pattern = "<tr>((?:<th>.*?</th>)+)</tr>"
With .Execute(sContent)
If .Count <> 1 Then
MsgBox "No header found"
Exit Do
End If
End With
.Pattern = "<th>(.*?)</th>"
With .Execute(sContent)
ReDim aHeader(0, 0 To .Count - 1)
For i = 0 To .Count - 1
aHeader(0, i) = .Item(i).SubMatches(0)
Next
End With
' Extract data
.Pattern = "<tr>((?:<td>.*?</td>)+)</tr>"
With .Execute(sContent)
If .Count = 0 Then
MsgBox "No rows found"
Exit Do
End If
ReDim aRows(0 To .Count - 1, 0)
For i = 0 To .Count - 1
aRows(i, 0) = .Item(i).SubMatches(0)
Next
End With
.Pattern = "<td>(.*?)</td>"
For i = 0 To UBound(aRows, 1)
With .Execute(aRows(i, 0))
For j = 0 To .Count - 1
If UBound(aRows, 2) < j Then ReDim Preserve aRows(UBound(aRows, 1), j)
aRows(i, j) = .Item(j).SubMatches(0)
Next
End With
Next
End With
Loop Until True
' Output
With ThisWorkbook.Sheets(1)
.Cells.Delete
Output2DArray .Cells(1, 1), aHeader
Output2DArray .Cells(2, 1), aRows
.Columns.AutoFit
End With
MsgBox "Completed"
End Sub
Sub Output2DArray(oDstRng As Range, aCells As Variant)
With oDstRng
.Parent.Select
With .Resize( _
UBound(aCells, 1) - LBound(aCells, 1) + 1, _
UBound(aCells, 2) - LBound(aCells, 2) + 1)
.NumberFormat = "#"
.Value = aCells
End With
End With
End Sub
All the data in the code could be easily obtained from browser developer tools on network tab after you click submit, as an example:
The above code returns the output for me as follows:

Adding tables in word with vba

I have been experimenting with adding tables in word from database.
So far I made a table in word document as a template
Then what I do is that I copy it into a new word document, search for DT and Dokumenttype and then replace it with the value I want. This is properly slow(however it seems to go extremly fast)and it would propberly be better to create it directly in word.
After creating the table i start adding rows to it, where the first column is to be hyperlinked. This is what seems to take time, it is only 235 rows total split on 11 tables but it takes almost a minute to create the 11 tables. So my question is how does you folks normally creates tables?
Do you create the header of the table, then keep adding rows?
Do you double loop, to find number of rows needed then create the whole table at one go?
Do you copy an array into the table to fill the rows? Then reloop to hyperlink the first column?
Output looks like this:
Below is my current code:
Option Explicit
Public Sub createDocOut(projectNumber As String, Optional reloadDatabase As Boolean = False)
Dim docOutArray() As String
Dim previousDokType As String
Dim doc_ As Document
Dim i As Long
Dim j As Integer
Dim k As Integer
Dim m As Integer
Dim sPercentage As Double
Dim numOfRows As Long
'Application.ScreenUpdating = False
docOutArray = Post.helpRequest("http://proto-ls/wordin.asp?Dok4=" & projectNumber)
If CPearson.IsArrayEmpty(docOutArray) Then
MsgBox "No document registered in database!"
End If
numOfRows = UBound(docOutArray, 1)
' creates a new document if needed otherwise it opens it
Set doc_ = NEwDocOut.createDocOutDocument(projectNumber)
If CustomProperties.getValueFromProperty(doc_, "_DocumentCount") = numOfRows And reloadDatabase = False Then
Application.ScreenUpdating = True
Exit Sub
Else
Selection.WholeStory
Selection.Delete
End If
'We add number of rows to document
Call CustomProperties.createCustomDocumentProperty(doc_, "_DocumentCount", numOfRows)
j = 0
previousDokType = ""
For i = LBound(docOutArray, 1) To numOfRows
'new table
If docOutArray(i, 1) <> previousDokType Then
If j > 0 Then
doc_.Tables(j).Select
Selection.Collapse WdCollapseDirection.wdCollapseEnd
Selection.MoveDown Unit:=wdLine, Count:=1
End If
j = j + 1
m = 2
Call NEwDocOut.addTable(doc_, docOutArray(i, 1), docOutArray(i, 2))
End If
'new row
With doc_.Tables(j)
.Rows(m).Select
Selection.InsertRowsBelow (1)
m = m + 1
' Hyper link the file
ActiveDocument.Hyperlinks.Add Anchor:=.Cell(m, 1).Range, _
Address:="z:\Prosjekt\" & projectNumber & docOutArray(i, 3), ScreenTip:="HyperLink To document", _
TextToDisplay:=FileHandling.GetFilenameFromPath(docOutArray(i, 3))
'loop through cells
For k = 3 To UBound(docOutArray, 2)
' .Cell(m, k - 2).Range.Font.Bold = False
' .Cell(m, k - 2).Range.Font.name = "Times New Roman"
' .Cell(m, k - 2).Range.Font.Size = 10
If k > 3 And k <> 8 Then
.Cell(m, k - 2).Range.Text = docOutArray(i, k)
End If
If k = 8 Then
.Cell(m, k - 2).Range.Text = Format(replace(docOutArray(i, k), ".", "/"), "mm.dd.yyyy")
End If
Next k
End With
previousDokType = docOutArray(i, 1)
Next i
'Application.ScreenUpdating = True
End Sub
'**********************************************************************
' ****** CREATE NEW DOCUMENT OUT **************************************
'**********************************************************************
Function createDocOutDocument(prosjektnumber As String) As Document
Dim dirName As String
Dim docOutname As String
Set createDocOutDocument = Nothing
' Hvis directory \Dokumentstyring\PFK ikke eksisterer, lag dette
dirName = "z:\Prosjekt\" & prosjektnumber
'change permision if needed
If Dir(dirName, vbDirectory) = "" And Not Settings.debugMy Then
MkDir dirName
End If
'filename of docOut
docOutname = dirName & "\" & prosjektnumber & "-Dokut.docx"
If FileHandling.doesFileExist(docOutname) Then
If FileHandling.openDocument(docOutname, True, True) Then
Set createDocOutDocument = ActiveDocument
Exit Function
End If
End If
'
' Add the tamplate for DocOut and save it to Doclist
'
Set createDocOutDocument = Documents.Add(Template:="Z:\Dokumentstyring\Config\DocOut.dotm", NewTemplate:=False)
createDocOutDocument.SaveAs filename:=docOutname
'Final check if document was created
If Not FileHandling.doesFileExist(docOutname) Then
Set createDocOutDocument = Nothing
End If
End Function
Function addTable(doc_ As Document, category As String, description As String)
doc_.Activate
'Insert out table
Selection.InsertFile filename:="Z:\Dokumentstyring\Config\Doklistut.docx", Range:="", _
ConfirmConversions:=False, link:=False, Attachment:=False
'Replace the DT with the category
If Not searchAll(doc_, "DT", category) Then
MsgBox "Failed to replace category in table"
End If
'Replace the Dokumenttype with the category
If Not searchAll(doc_, "Dokumenttype", description) Then
MsgBox "Failed to replace document type in table"
End If
End Function

Excel VBA, nested loops / hide rows based on numbers

Dear stackoverflow community
At work I have to write a macro which should be able to hide rows based on numbers in a column. Those can be multiple ones in one cell and the input should also allow to show more than one number at a time.
for example:
row 1: 20, 30, 15
row 2: 20
row 3: 13, 76
So if I enter 20, 30, it should only show rows 1 & 2)
I usually code with Java / c# and Im new to VBA, so Id really appreciate help:
My plan was to show a input box and split those numbers into an array.
Then i wanna go through each row with a for-Loop, in which i added two for each loops to check if any numbers equal. If not, hide row. If so, show and then i want to exit both for each loops and go to the next row. To exit nested loops, i tried using a do while boolean but it doesnt seem to work.
Right now it only shows the rows with all the input numbers (only row1 in example).
Sub SortingTest()
Dim numbers() As String
myNum = Application.InputBox("Enter BKPS (separate multiples by , )")
numbers = Split(myNum, ",", -1, compare)
'Userinput Vars
Dim row As Integer
row = 1
Dim saveNumber As String
'Looping Vars
Dim existingNum As String
Dim existingNumsArray() As String
Dim checkRows As Long
Dim saveElement As String
Dim done As Boolean
done = False
' Range("B3").Value = 10
' Saves the Input as Array:
For Each Element In numbers
saveNumber = Element
Cells(2, row).Value = saveNumber
row = row + 1
Next Element
Dim b As Integer
Do While done = False
For b = 1 To 100 'hardcoded, should be length of document. b == row;
existingNum = Cells(b, 3).Value
existingNumsArray = Split(existingNum, ",", -1, compare)
' loop thru input numbers
For Each Element In numbers
saveElement = Element
'loop thru given numbers
For Each inputElement In existingNumsArray
If saveElement <> inputElement Then
Rows(b).Hidden = True
ElseIf saveElement = inputElement Then
Rows(b).Hidden = False
done = True
Exit For
End If
Next
Next
Next
Loop
End Sub
Thank you very much for you answer. Yours hid all the rows, so i adjusted it to show them.
Option Explicit
Function ArrOr(a As Variant, b As Variant) As Boolean
Dim runner As Variant
ArrOr = True
If IsArray(a) Then
For Each runner In a
If ArrOr(runner, b) Then Exit Function
Next
Else
For Each runner In b
If Trim(a) = Trim(runner) Then Exit Function
Next
End If
ArrOr = False
End Function
Sub SortingBKPS()
Dim numbers As Variant, vars As Variant, i As Long, xRows As Range
numbers = Split(Application.InputBox("Enter BKPS (separate multiples by , )"), ",")
With Sheets("Sheet1")
vars = .Range("B1", .Cells(.Rows.Count, 2).End(xlUp)).Value2
For i = 2 To UBound(vars)
.Rows(i).EntireRow.Hidden = True
If ArrOr(Split(vars(i, 1), ","), numbers) Then
If xRows Is Nothing Then
Set xRows = .Rows(i)
Else
Set xRows = Union(xRows, .Rows(i))
End If
End If
Next
xRows.EntireRow.Hidden = False
End With
End Sub
By splitting it up it is very easy to do:
Option Explicit
Function ArrOr(a As Variant, b As Variant) As Boolean
Dim runner As Variant
ArrOr = True
If IsArray(a) Then
For Each runner In a
If ArrOr(runner, b) Then Exit Function
Next
Else
For Each runner In b
If Trim(a) = Trim(runner) Then Exit Function
Next
End If
ArrOr = False
End Function
Sub SortingTest()
Dim numbers As Variant, vars As Variant, i As Long, xRows As Range
numbers = Split(Application.InputBox("Enter BKPS (separate multiples by , )"), ",")
With Sheets("Sheet1")
vars = .Range("B1", .Cells(.Rows.Count, 2).End(xlUp)).Value2
For i = 1 To UBound(vars)
If ArrOr(Split(vars(i, 1), ","), numbers) Then
If xRows Is Nothing Then
Set xRows = .Rows(i)
Else
Set xRows = Union(xRows, .Rows(i))
End If
End If
Next
xRows.EntireRow.Hidden = True
End With
End Sub
by running this code line by line, it should be pretty much self explaining (also knowing you have already some knowledge in "coding")
Still, if you have any questions, just ask ;)
You can also do it the following way:
Sub SortingTest()
Dim numbers As Variant
Dim RangeCompare As Range
Dim MyRow As Integer
Dim NumFound As Boolean
numbers = Application.InputBox("Please,list the values in this format: " & _
vbCrLf & "{value, value, value, ...}", _
Default:="{#, #, #}", Type:=64)
For MyRow = 1 To Cells(Rows.Count, 1).End(xlUp).row
Set RangeCompare = Range(Cells(MyRow, 1), Cells(MyRow, Columns.Count).End(xlToLeft))
NumFound = False
For Each rCell In RangeCompare
For Each Element In numbers
If rCell = Element Then
NumFound = True
Exit For
End If
Next Element
If NumFound = True Then Exit For
Next rCell
If NumFound = False Then
Rows(MyRow).Hidden = True
End If
Next MyRow
End Sub
I think it's easy to understand but feel free to ask for explanation.

How to get the value between two asterisk in excel?

How to get the value between two asterisk in excel?
for example:
I have these: TXI*GS*346.32*13*SP*ON*3***103634408RT0001
I only want to get the value 346.32
i these data like this for A1:A20 how can i replace them all using VBA?
Sub useSplit()
Dim s As String
s = "TXI*GS*346.32*13*SP*ON*3***103634408RT0001"
Dim a() As String
a = Split(s, "*")
Dim i As Long
For i = 0 To UBound(a)
Debug.Print a(i)
Next
End Sub
Sub extractFirstNumber()
Set objRegEx = CreateObject("vbscript.regexp")
' Match numbers of the form 123 or 123.45
objRegEx.Pattern = "\d+(\.\d*)?"
' Iterate over the first 20 rows in first column
For i = 1 To 20
Set objMatch = objRegEx.Execute(Cells(i, 1).Value)
If objMatch.Count = 1 Then
' If there is a match, replace the cell value
Cells(i, 1).Value = objMatch(0)
End If
Next i
End Sub
Edit
Sub extractFirstAndThirdNumber()
Set objRegEx = CreateObject("vbscript.regexp")
' Match numbers of the form 123 or 123.45 between asteriks
objRegEx.Pattern = "\*(\d+(\.\d*)?)"
objRegEx.Global = True
' Iterate over the first 20 rows in first column
For i = 1 To 20
Set objMatch = objRegEx.Execute(Cells(i, 1).Value)
If objMatch.Count >= 2 Then
' If there is a match, replace the cell value
'Cells(i, 1).Value = objMatch(0)
Cells(i, 3).Value = objMatch(0).SubMatches(0)
Cells(i, 4).Value = objMatch(2).SubMatches(0)
End If
Next i
End Sub