Open a recordset in VS2017 like I could in VB6 for MS Access table - visual-studio-2017

I am a long time VB6 guy, and feel squeezed into VS2017
I need your help with a VS2017 equivlent of
dim db as database
dim rs as recordset
db=opendatabase("path to .MDB")
rs = db.openrecordset("select * where myfield ="mine", order by fieldage") 'This SQL bit is easy.
'Then rs.movenext or rs.moveprevious etc etc
'Also it would help if I could say Textbox1.text = rs(3)
This is to be rolled out to more than one PC, so having to set a specific data connection in the PC config is not practical.
Thanks for reading this far.

I don't know if this would tick off all your needs, but it's longer than a comment, so I'm surfacing it as a possible solution.
It looks like you're doing VB.net? I encountered a similar challenge when I converted directly from VB6 -> C# using a tool I wrote and then made public.
https://github.com/bhoogter/VB6TocSharp (Yes, I wrote this. Yes, it's free).
To get around it, we used the standard System.Data and System.Data.OleDb packages. These did not have the convenience methods provided like .MoveNext() or .MovePrevious(), and also, as you pointed out, could not be referenced by rs(3), let alone some of the easy positioning and filtering we were converting from.
That said, we chose to wrap the objects returned from the database calls with a Recordset class, and use those provide the interface we wanted.
Of course, the original was written in C#, available here:
https://github.com/bhoogter/VB6TocSharp/blob/master/extras/Recordset.cs
But, I put together a VB.NET port of the same, if intersted, linked, and also included here.
https://github.com/bhoogter/VB6TocSharp/blob/master/extras/vb.net/recordset.vb
Of note is the use of a few sub-classes contained within the Recordset class that can make life easier. But, what is available right away is the methods you mentioned (MoveNext, MovePrevious, RS('fieldname'))... Note that in VB6, RS(f) would return a Field object, and the default property of that field object was .Value. This tries to maintain back-wards compatibility by bypassing the Field object and just returning .Fields[i].Value, so you don't have to change your existing code. This saves time and effort in conversion. And, if there is some interface you're missing, you control this layer so you can add and/or modify as suits your conversion needs.
The VB.net ported version is as follows... It is a conversion of the C# one, so I can't guarantee it's 100% perfect, but it should be enough to demonstrate the point. YMMV.
Imports System.Data
Imports System.Data.OleDb
' Recordset object. Used to wrap other data objects to 'simulate' VB6.
Public Class Recordset
Public Source As String = ""
Public Parameters As Dictionary(Of Object, Object)
Public Database As String = ""
Public QuietErrors As Boolean = False
Private mAddingRow As Boolean = False
Public ReadOnly Property AddingRow As Boolean
Get
Return mAddingRow
End Get
End Property
Private connection As OleDbConnection
Private adapter As OleDbDataAdapter
Private table As DataTable
Private filteredTable As DataTable
Private mFilter As String
Public Sub New()
End Sub
Public Sub New(table As DataTable, adapter As OleDbDataAdapter, connection As OleDbConnection)
Me.connection = connection
Me.adapter = adapter
Me.table = table
End Sub
Public Sub New(SQL As String, File As String, Optional QuietErrors As Boolean = False, Optional Parameters As Dictionary(Of Object, Object) = Nothing)
Me.Source = SQL
Me.Parameters = Parameters
Me.Database = File
Me.QuietErrors = QuietErrors
Open()
End Sub
Public Sub Close()
Try
connection?.Close()
Catch
' just suppress
End Try
connection = Nothing
adapter = Nothing
table = Nothing
filteredTable = Nothing
End Sub
Public Shared Sub sqlExecutionError(mSQL As String, e As Exception)
Dim T As String = ""
T &= "getRecordSet Failed: " & e.Message & vbCrLf
T &= vbCrLf
T &= mSQL & vbCrLf
T &= vbCrLf
T &= "ERROR:" & e.Message
T = T.Replace("$EDESC", e.Message)
'ErrMsg = Replace(ErrMsg, "$ENO", Err().Number)
T = T.Replace("$ESRC", e.Source)
MsgBox("Database Error: " + T, 0, "Error")
'CheckStandardErrors() ' Bookmark/updateable query
End Sub
Private Function ConnectionString(file As String) As String
Return "PROVIDER=Microsoft.Jet.OLEDB.4.0Data Source=" + file
End Function
Public Property AbsolutePosition As Integer = -1
Public Property Position As Integer
Get
Return AbsolutePosition
End Get
Set(value As Integer)
AbsolutePosition = value
End Set
End Property
Public ReadOnly Property RecordCount As Integer
Get
If Not table Is Nothing Then
If Not table.Rows Is Nothing Then
Return table.Rows.Count
End If
End If
Return 0
End Get
End Property
Public ReadOnly Property EOF As Boolean
Get
Return AbsolutePosition >= RecordCount
End Get
End Property
Public ReadOnly Property BOF As Boolean
Get
Return AbsolutePosition = 0
End Get
End Property
Public Function FieldExists(F As String) As Boolean
If Not table Is Nothing Then
If Not table.Columns Is Nothing Then
Return table.Columns.Contains(F)
End If
End If
Return False
End Function
Public Function MoveFirst() As Integer
AbsolutePosition = 0
Return 0
End Function
Public Function MoveNext() As Integer
Return If(++AbsolutePosition < RecordCount, AbsolutePosition, AbsolutePosition = RecordCount)
End Function
Public Function MovePrevious() As Integer
Return If(--AbsolutePosition >= 0, AbsolutePosition, AbsolutePosition = 0)
End Function
Public Function MoveLast() As Integer
AbsolutePosition = RecordCount - 1
Return AbsolutePosition
End Function
Public ReadOnly Property Fields As RecordsetFields
Get
If AbsolutePosition >= 0 And AbsolutePosition < RecordCount Then Return New RecordsetFields(table.Rows(AbsolutePosition))
Throw New ArgumentOutOfRangeException("Either EOF or BOF is true.")
End Get
End Property
Public ReadOnly Property FieldNames As List(Of String)
Get
If IsNothing(table) Then Return Nothing
Dim result As List(Of String) = New List(Of String)
For Each item As DataColumn In table.Columns
result.Add(item.ColumnName)
Next
Return result
End Get
End Property
Public ReadOnly Property Field As PropIndexer(Of Object, Object)
Get
Return New PropIndexer(Of Object, Object)(
Function(k As Object)
Return Fields(k).Value
End Function,
Function(k As Object, v As Object)
Fields(k).Value = v
End Function
)
End Get
End Property
Default Property Item(field As Object) As Object
Get
Return GetField(field)
End Get
Set
SetField(field, Value)
End Set
End Property
Public Function GetField(key As Object) As Object
Return Fields(key).Value
End Function
Public Sub SetField(key As Object, value As Object)
Fields(key).Value = value
End Sub
Public Function GetRows() As List(Of List(Of Object))
Dim tableEnumerable As Object = table.AsEnumerable()
Dim tableList As Object = tableEnumerable.ToArray().ToList()
Return tableList.ToList() _
.Select(Function(r As Object)
Return r.ItemArray.ToList()
End Function) _
.ToList()
End Function
Public Property Filter As String
Get
Return mFilter
End Get
Set(value As String)
mFilter = value
If String.IsNullOrEmpty(value) Then
filteredTable = Nothing
Return
End If
filteredTable = table.Select(mFilter).CopyToDataTable()
End Set
End Property
Protected Function Find(v As String) As Boolean
Dim temp As DataTable = table.Select(mFilter).CopyToDataTable()
If temp.Rows.Count = 0 Then Return False
Dim X As Integer = table.Rows.IndexOf(temp.Rows(0))
AbsolutePosition = X
Return True
End Function
Private Sub Open()
Const maxTries = 5
If Dir(Database) = "" Then
MsgBox("Database Not Found: " + Database)
Return
End If
Dim result As DataSet = New DataSet()
connection = New OleDbConnection(ConnectionString(Database))
Dim Command As OleDbCommand = New OleDbCommand(Source, connection)
For Each Key In Parameters.Keys
Dim param As OleDbParameter = Command.CreateParameter()
param.ParameterName = Key
param.Value = Parameters(Key)
Next
adapter = New OleDbDataAdapter(Command)
Try
connection.Open()
adapter.FillSchema(result, SchemaType.Source)
adapter.Fill(result, "Default")
Catch e As Exception
If Not QuietErrors Then sqlExecutionError(Source, e)
Finally
connection.Close()
End Try
table = result.Tables("Default")
End Sub
Public Sub Update()
Dim cb As OleDbCommandBuilder = New OleDbCommandBuilder(adapter)
cb.QuotePrefix = "["
cb.QuoteSuffix = "]"
Try
connection.Open()
adapter.UpdateCommand = cb.GetUpdateCommand()
adapter.Update(table)
Catch e As Exception
If Not QuietErrors Then sqlExecutionError(adapter.DeleteCommand.ToString(), e)
Finally
connection.Close()
End Try
mAddingRow = False
End Sub
Public Sub AddNew()
Dim newRow As DataRow = table.NewRow()
table.Rows.InsertAt(newRow, table.Rows.Count)
AbsolutePosition = table.Rows.Count - 1
mAddingRow = True
End Sub
Public Sub Delete()
Dim cb As OleDbCommandBuilder = New OleDbCommandBuilder(adapter)
Try
connection.Open()
adapter.DeleteCommand = cb.GetDeleteCommand()
adapter.Update(table)
Catch e As Exception
If Not QuietErrors Then sqlExecutionError(adapter.UpdateCommand.ToString(), e)
Finally
connection.Close()
End Try
End Sub
Public Class RecordsetFields
Implements ICollection
Private row As DataRow = Nothing
Public Sub New(row As DataRow)
Me.row = row
End Sub
Public ReadOnly Property Count As Integer
Get
Return row.Table.Columns.Count
End Get
End Property
Public SyncRoot As Object = Nothing
Public IsSynchronized As Boolean = False
Private Sub ICollection_CopyTo(array As Array, index As Integer) Implements ICollection.CopyTo
Throw New InvalidOperationException("Not valid on object")
End Sub
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return row.Table.Columns.GetEnumerator()
End Function
Default Public ReadOnly Property Item(x As Object) As RecordsetField
Get
Dim C As DataColumn = row.Table.Columns(x)
Return New RecordsetField(row, x)
End Get
End Property
Private ReadOnly Property ICollection_Count As Integer Implements ICollection.Count
Get
Throw New NotImplementedException()
End Get
End Property
Private ReadOnly Property ICollection_IsSynchronized As Boolean Implements ICollection.IsSynchronized
Get
Throw New NotImplementedException()
End Get
End Property
Private ReadOnly Property ICollection_SyncRoot As Object Implements ICollection.SyncRoot
Get
Throw New NotImplementedException()
End Get
End Property
End Class
Public Class RecordsetField
Public Const adSmallInt As Integer = 2 ' Integer SmallInt
Public Const adInteger As Integer = 3 ' AutoNumber
Public Const adSingle As Integer = 4 ' Single Real
Public Const adDouble As Integer = 5 ' Double Float Float
Public Const adCurrency As Integer = 6 ' Currency Money
Public Const adDate As Integer = 7 ' Date DateTime
Public Const adIDispatch As Integer = 9 '
Public Const adBoolean As Integer = 11 ' YesNo Bit
Public Const adVariant As Integer = 12 ' Sql_Variant(SQL Server 2000 +) VarChar2
Public Const adDecimal As Integer = 14 ' Decimal *
Public Const adUnsignedTinyInt As Integer = 17 ' Byte TinyInt
Public Const adBigInt As Integer = 20 ' BigInt(SQL Server 2000 +)
Public Const adGUID As Integer = 72 ' ReplicationID(Access 97 (OLEDB)), (Access 2000 (OLEDB)) UniqueIdentifier (SQL Server 7.0 +)
Public Const adWChar As Integer = 130 ' NChar(SQL Server 7.0 +)
Public Const adChar As Integer = 129 ' Char Char
Public Const adNumeric As Integer = 131 ' Decimal(Access 2000 (OLEDB)) Decimal
Public Const adBinary As Integer = 128 ' Binary
Public Const adDBTimeStamp As Integer = 135 ' DateTime(Access 97 (ODBC)) DateTime
Public Const adVarChar As Integer = 200 ' Text(Access 97) VarChar VarChar
Public Const adLongVarChar As Integer = 201 ' Memo(Access 97)
Public Const adVarWChar As Integer = 202 ' Text(Access 2000 (OLEDB)) NVarChar (SQL Server 7.0 +) NVarChar2
Public Const adLongVarWChar As Integer = 203 ' Memo(Access 2000 (OLEDB))
Public Const adVarBinary As Integer = 204 ' ReplicationID(Access 97) VarBinary
Public Const adLongVarBinary As Integer = 205 ' OLEObject Image Long Raw *
Private Row As DataRow = Nothing
Public Name As Object = ""
Public Size As Integer = 0
Public Sub New(Row As DataRow, Name As Object)
Me.Row = Row
Me.Name = Name
End Sub
Public Property Value As Object
Get
Return Row(Name)
End Get
Set(value As Object)
Row(Name) = value
End Set
End Property
Public ReadOnly Property Type As Object
Get
Return Row.Table.Columns(Name).DataType
End Get
End Property
End Class
Public Class PropIndexer(Of I, V)
Public Delegate Sub setProperty(idx As I, value As V)
Public Delegate Function getProperty(idx As I)
Public getter As getProperty
Public setter As setProperty
Public Sub New(g As getProperty, s As setProperty)
getter = g
setter = s
End Sub
Public Sub New(g As getProperty)
getter = g
setter = AddressOf setPropertyNoop
End Sub
Public Sub New()
getter = AddressOf getPropertyNoop
setter = AddressOf setPropertyNoop
End Sub
Private Sub setPropertyNoop(idx As I, value As V)
' NOOP. Intentionally left blank.
End Sub
Private Function getPropertyNoop(idx As I) As V
Return CType(Nothing, V)
End Function
Default Public Property Item(ByVal nIndex As I) As V
Get
Return getter.Invoke(nIndex)
End Get
Set
setter.Invoke(nIndex, Value)
End Set
End Property
End Class
End Class

Related

Crawling web page links through Visaul Basic 2008

I have tried to convert one of my Visual Basic 6 programs to Visual Basic.NET. This program basically crawls email and mobile number data from a web page link. This program works great in Visual Basic 6 but after converting to Visual Basic.NET is not providing any function or result in .NET.
Imports VBScript_RegExp_55
Imports System.Collections.Specialized
Imports System.Diagnostics
Public Class autoextratorform
Dim emailsearch As New ListViewItem()
Dim numbersearch As New ListViewItem
Private Declare Function SendMessageByString _
Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As String) _
As Long
Private Const LB_SELECTSTRING = &H18C
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private WithEvents cIE As InternetHtml
Private WithEvents cExtLinks As cExtractLinks
Private cGSearch As cGoogleSearch
Dim Excel As Object
Dim Excelsheet As Object
Dim a() As String
Dim b() As String
Dim c() As String
Dim i As Integer
' Needs reference to Microsoft VBscript Regular Expressions I recomend ver 5.5.
'
Dim baseurl As String ' var to store base url so we can build the full path
Dim dVisited ' Dictionary to hold visited urls = I think Missing here
Dim dEmail ' dictionary to hold emails = I think Missing here
Dim dnumber ' = I think Missing here
Dim dweb '= I think Missing here
' We are putting the emails in a list also, for user feed back
'It would be less momery intensive and faster to just keep these in the dictionry object
'which allows to easily tell if the email already exist
Dim regxPage ' var to hold regular expression to extract urls
Dim regxEmail ' var to hold regular expression to extract emails
Dim regnumber
Dim regweb
Dim Match, Matches As String ' we use these to store are regx matches
Dim Match1, Matches1 As String
Dim Match2, Matches2 As String
' Regular expressions are super powerfull and have been a part of unix for a long time
' goto the form load event to see the regex initialization
' to learn more about regular expressions and to download the latest scripting runtime see
' http://msdn.microsoft.com/scripting/default.htm?/scripting/vbscript/techinfo/vbsdocs.htm
Dim email, pageurl, mnumber, sweb As String
' The above is only because dictionary.exist does not work directly on Match var
Dim stopcrawl As Integer ' Used to exit crawl loop
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Select Case ComboBox1.SelectedIndex
Case 0
ListBox2.Items.Clear()
ListBox2.Items.Add("http://classads.jang.com.pk/default.asp?cityid=1")
ListBox2.Items.Add("http://www.merapakistan.com/classifieds/")
ListBox2.Items.Add("http://olx.com.pk/")
ListBox2.SelectedIndex = 0
txtStartUrl.Text = ListBox2.Text
Case 1
ListBox2.Items.Clear()
ListBox2.Items.Add("http://www.locanto.com.pk/")
ListBox2.Items.Add("http://pakistanclassifiedads.com/")
ListBox2.Items.Add("http://pkr.com.pk/")
txtStartUrl.Text = ListBox2.Text
Case 2
ListBox2.Items.Clear()
ListBox2.Items.Add("http://adpost.pk/")
ListBox2.Items.Add("http://page.com.pk/")
ListBox2.Items.Add("http://www.clasf.pk/")
ListBox2.SelectedIndex = 0
txtStartUrl.Text = ListBox2.Text
Case 3
ListBox2.Items.Clear()
ListBox2.Items.Add("http://www.nelaam.com/")
ListBox2.Items.Add("http://www.asani.com.pk/")
ListBox2.Items.Add("http://freepost.com.pk/")
ListBox2.SelectedIndex = 0
txtStartUrl.Text = ListBox2.Text
End Select
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command1.Click
stopcrawl = 0 ' set stop crawl so we do not exit loop
If txtStartUrl.Text & "" = "" Then
lblresult.Text = ("Please Load your Desired Site List !")
Exit Sub
ElseIf txtStartUrl.Text & "" = "http://" Then
lblresult.Text = ("Please Load your Desired Site List !")
Exit Sub
ElseIf txtStartUrl.Text = "" Then
lblresult.Text = ("Please Load your Desired Site List !")
Exit Sub
End If
' the above should really check for a valid url, but I am a lazy PERL programmer
ListBox1.Items.Add(txtStartUrl.Text) 'add item to list
Label16.Text = (ListBox2.Items.Count - 1)
Label8.Text = (ListBox2.Items.Count)
lblresult.Text = " Start service for searching Email address and Mobile Numbers"
Command1.Enabled = False
ComboBox1.Enabled = False
LaVolpeButton4.Enabled = True
'UPGRADE_ISSUE: (2064) ComboBox property Combo1.Locked was not upgraded. More Information: https://docs.mobilize.net/vbuc/ewis#2064
LaVolpeButton8.Enabled = False
LaVolpeButton9.Enabled = False
txtStartUrl.ReadOnly = True
crawl() ' and were off
End Sub
Private Sub autoextrator_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
With listnumber
.Columns.Clear()
.Columns.Add("Count!", CInt(Width * 0.1))
.Columns.Add("Mobile Number!", CInt(Width * 0.2))
.Columns.Add("Web URL!", CInt(Width * 0.68))
End With
With listemail
.Columns.Clear()
.Columns.Add("Count!", CInt(Width * 0.1))
.Columns.Add("Email Address!", CInt(Width * 0.2))
.Columns.Add("Web URL!", CInt(Width * 0.68))
End With
'initialize dictionary and regx objects
dVisited = CreateObject("Scripting.Dictionary")
dVisited.CompareMode = CompareMethod.Binary
dEmail = CreateObject("Scripting.Dictionary")
dEmail.CompareMode = CompareMethod.Binary
dnumber = CreateObject("Scripting.Dictionary")
dnumber.CompareMode = CompareMethod.Binary
dweb = CreateObject("Scripting.Dictionary")
dweb.CompareMode = CompareMethod.Binary
Dim counting1 As String
Dim counting2 As String
regxPage = New VBScript_RegExp_55.RegExp() ' Create a regular expression.
regxPage.Pattern = "HREF=""[^""#]+[.][^""#]+" ' Set pattern."
regxPage.IgnoreCase = True ' Set case insensitivity.
regxPage.Global = True ' Set global applicability.
regxEmail = New VBScript_RegExp_55.RegExp() ' Create a regular expression.
regxEmail.Pattern = "\b[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,4}\b" ' Set pattern."
regxEmail.IgnoreCase = True ' Set case insensitivity.
regxEmail.Global = True ' Set global applicability.
regnumber = New VBScript_RegExp_55.RegExp()
counting1 = "(\+92)-?\d{3}-?\d{7}"
counting2 = "(?:0092|0|\+92)-?\d{3}-?\d{7}"
regnumber.Pattern = counting1
regnumber.Pattern = counting2
regnumber.IgnoreCase = True
regnumber.Global = True
cIE = New InternetHtml()
cGSearch = New cGoogleSearch()
cExtLinks = New cExtractLinks()
End Sub
Sub crawl()
While ListBox1.Items.Count > 0 ' loop while list has data
If stopcrawl = 1 Then GoTo exitcrawl
getpage(ListBox1.Items(0)) ' This is the heart of the prog, except for the regx = I think Missing here
' stuff in the form load event
ListBox1.Items.Remove(0) ' remove item from list
End While
ListBox2.Items.Remove(ListBox2.SelectedIndex)
If ListBox2.SelectedIndex < ListBox2.Items.Count - 1 Then
ListBox2.SelectedIndex += 1
txtStartUrl.Text = ListBox2.Items.ToString
exitcrawl:
If ListBox2.Items.Count = 0 Then
MessageBox.Show("Searching has completed !", "Done ! searching", MessageBoxButtons.OK, MessageBoxIcon.Information)
txtStartUrl.ReadOnly = False
txtStartUrl.Text = ""
Label3.Text = "-----------------------------------------------------------"
LaVolpeButton4.Enabled = False
Command1.Enabled = True
LaVolpeButton8.Enabled = True
LaVolpeButton9.Enabled = True
End If
End If
End Sub
Sub getpage(ByVal page As String)
On Error Resume Next
If dVisited.Contains(page) Then
Exit Sub
Else
dVisited.Add(page, 1) ' add page to dVisited dictionary
Label6.Text = CStr(ListBox1.Items.Count)
Label14.Text = CStr(dVisited.Count)
Label3.Text = page
End If
baseurl = getpath(page) ' build full url - see getpath
TextBox1.Text = ""
If ListBox1.Items.Count > 5000 Then Exit Sub ' sets the maximum cache (so we don't run out of mem)
Using wc As New System.Net.WebClient
TextBox1.Text = wc.DownloadString(page)
End Using
Matches = regxPage.Execute(TextBox1.Text) ' Execute search.
For Each Me.Match In Matches
pageurl = Match
If InStr(1, pageurl, "http://", vbTextCompare) Then
If dVisited.Exists(pageurl) = False Then ListBox1.Items.Add(Mid(pageurl, 7))
Else
If dVisited.Exists(baseurl & Mid(pageurl, 7)) = False Then ListBox1.Items.Add(baseurl & Mid(pageurl, 7))
End If
Next
' search for email
Matches = regxEmail.Execute(TextBox1.Text) ' Execute search.
For Each Me.Match In Matches ' Iterate Matches collection.
' check if email exist
email = Match
Debug.Print(email & dEmail.Exists(email))
If dEmail.Exists(email) = False Then
dEmail.Add((email), 1)
Dim d As Integer
d = listemail.Items.Count
d = d + 1
emailsearch = listemail.Items.Add(d)
emailsearch.SubItems.Add(email.ToString)
emailsearch.SubItems.Add(pageurl.ToString)
ListBox3.Items.Add(email)
Label10.Text = listemail.Items.Count
End If
Next
Matches1 = regnumber.Execute(TextBox1.Text)
For Each Me.Match1 In Matches1
mnumber = Match1
Debug.Print(mnumber & dnumber.Exists(mnumber))
If dnumber.Exists(mnumber) = False Then
dnumber.Add((mnumber), 1)
Dim c As Integer
c = listnumber.Items.Count
c = c + 1
numbersearch = listnumber.Items.Add(c)
numbersearch.SubItems.Add(mnumber.ToString)
numbersearch.SubItems.Add(pageurl.ToString)
Label12.Text = listnumber.Items.Count
End If
Next
End Sub
Function getpath(ByVal URL As String) As String
' look for the last / and get a string up to that location
Dim lastbar As Integer = URL.LastIndexOf("/") + 1
Dim tmppath As String = URL.Substring(0, Math.Min(lastbar, URL.Length))
If tmppath = "http://" Then tmppath = URL ' full path already so return url
Return tmppath
End Function
Public Function StripOut(ByVal From As String, ByVal What As String) As String
Dim result As String = ""
result = From
For i As Integer = 1 To Strings.Len(What)
result = result.Replace(What.Substring(i - 1, Math.Min(1, What.Length - (i - 1))), "")
Next i
Return result
End Function
Private Sub LaVolpeButton4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LaVolpeButton4.Click
stopcrawl = 1
MsgBox(" Service has Stoped by USER !")
LaVolpeButton4.Enabled = False
Command1.Enabled = True
End Sub
Private Sub LaVolpeButton8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LaVolpeButton8.Click
Dim strData As String = ""
Dim strQ() As String
Dim intFile As Integer
' Set up the Common Dialog initial Directory
' to the application path. Filter for Text and All files
' Prompt the user to select a file
'
cmd.InitialDirectory = My.Application.Info.DirectoryPath
cmd.Filter = "Text Files(*.txt)|*.txt|All Files(*.*)|*.*"
cmd.Title = "Select Email Addresses File"
cmd.ShowDialog()
If cmd.FileName <> "" Then
'
' If the user selected a file
' open and read the entire contents
' then split it into records
'
intFile = FileSystem.FreeFile()
FileSystem.FileOpen(intFile, cmd.FileName, OpenMode.Input)
strData = FileSystem.InputString(intFile, FileSystem.LOF(intFile))
FileSystem.FileClose(intFile)
strQ = strData.Split(CChar(Environment.NewLine))
'
' Populate the texbox array with the questions
' (either the number of textboxes in the control array or
' number of questions, which ever is the smaller)
For Each strQ_item As String In strQ
ListBox2.Items.Add(strQ_item)
Next strQ_item
txtStartUrl.Text = ListBox2.Text
End If
End Sub
End Class
2- This is Visual basic 6 Code that works perfect.
Dim baseurl As String ' var to store base url so we can build the full path
Dim dVisited As Dictionary ' Dictionary to hold visited urls
Dim dEmail As Dictionary ' dictionary to hold emails
Dim dnumber As Dictionary
Dim dweb As Dictionary
Sub crawl()
While List1.ListCount > 0 ' loop while list has data
If stopcrawl = 1 Then GoTo exitcrawl
getpage List1.List(0) ' This is the heart of the prog, except for the regx
' stuff in the form load event
List1.RemoveItem (0) ' remove item from list
Wend
List2.RemoveItem (List2.ListIndex)
If List2.ListIndex < List2.ListCount - 1 Then
List2.ListIndex = List2.ListIndex + 1
txtStartUrl = List2.Text
Command1_Click
Else
exitcrawl:
If List2.ListCount = 0 Then
MsgBox "Searching has completed !", vbInformation, "Done ! searching"
WebBrowser1.Stop
txtStartUrl.Locked = False
txtStartUrl.Text = ""
Label3.Caption = "-----------------------------------------------------------"
LaVolpeButton4.Enabled = False
Command1.Enabled = True
LaVolpeButton8.Enabled = True
LaVolpeButton9.Enabled = True
End If
End If
End Sub

IF then Else code in my SSRS report not working

below is my code for identifying format of the amount.
if chargeNum is not equal to invoiceNumber, then set currency to "C"
else currency to "N"
then i'll set the chargeNum to be equal to the invoiceNumber before returning the currency
my code below is not working. What am I missing?
Thank you !
Public Shared invoiceNumber as integer
Public Shared currency as string
Public chargeNum As Integer=0
Public subNum As Integer=0
Public shared Pagenumber as integer
public dim currentgroup as string
public shared dim offset as integer = 0
Public Shared Function getInvoiceNumber() As Integer
Return invoiceNumber
End Function
Public Shared Function setInvoiceNumber(invoice as integer)
invoiceNumber=invoice
End Function
Public Shared Function getCurrency() As string
if chargeNum <> invoiceNumber then
currency ="C"
else
currency="N"
end if
chargeNum=invoiceNumber
Return currency
End Function```

Multiply only numbers in a mixed string [VB.Net]

Let's say I have a string "N4NSD3MKF34MKMKFM53" and i want to multiply the string * 2 to get
N8NSD6MKF68MKMKFM106 How would I go about doing this?
Ok, I might as well give you the Regex solution as long as I'm here. But I caution you not to use it unless you understand what it's doing. It's never a good idea to just copy and paste code that you don't fully understand.
Dim input As String = "N4NSD3MKF34MKMKFM53"
Dim output As String = Regex.Replace(
input,
"\d+",
Function(x) (Integer.Parse(x.Value) * 2).ToString())
You can try the following code:
Public Class Program
Public Shared Sub Main(args As String())
Const expression As String = "N4NSD3MKF34MKMKFM53"
Dim result = MultiplyExpression.Calculate(expression)
Console.WriteLine(result)
End Sub
End Class
Class MultiplyExpression
Public Shared Function Calculate(expression As String) As String
Dim result = String.Empty
For Each c In expression
Dim num As Integer
If Int32.TryParse(c.ToString(), num) Then
result += (num * 2).ToString()
Else
result += c
End If
Next
Return result
End Function
End Class
Output: N8NSD6MKF68MKMKFM106

VB.Net: Regular Expressions

I'm creating an application that will be able to tell me who is logged onto what PC, in the manufacturing center, where I work.
I'm using psexec's psloggedon cmd process to get me the information for me and a VB.net windows application to show me the information.
I begin by first querying a databse for all the PC's we currently have active and dumping the data into a datagridview object. (Shown below)
Private Sub Button(sender As System.Object, e As System.EventArgs) Handles btngetPC.Click
'GET AREAS FROM DATABASE
Dim ds As New DataSet()
Dim db As String = "QUERY STRING GOES HERE"
'CONNECT TO DATABASE
Using da As New SqlDataAdapter(db, MySQLConnection)
da.Fill(ds, "MACHINE_NAME")
End Using
With datagridView1
.DataSource = ds.Tables("MACHINE_NAME")
End With
'ADD COLUMN TO DATAGRIDVIEW
datagridView1.Columns.Add("LOGGED_IN", "LOGGED_IN")
MySQLConnection.Close()
End Sub
Once I have my datagridview object filled out with all my active PC's, I can then use the machine names to run the psloggedon cmd to get who is logged in. I do so by using:
Private Sub execute(sender As Object, e As EventArgs) Handles bntExecuteCmd.Click
'COUNT ENTRIES
Dim RowCount As Integer = datagridView1.RowCount
''EXECUTE CMD
For i = 0 To RowCount - 2
'PERFORM PSLOGGEDON ROUTINE
Dim Proc1 As New Process
Proc1.StartInfo = New ProcessStartInfo("psloggedon")
Proc1.StartInfo.Arguments = "-l \\" & datagridView1.Rows(i).Cells(1).Value & ""
Proc1.StartInfo.RedirectStandardOutput = True
Proc1.StartInfo.UseShellExecute = False
Proc1.StartInfo.CreateNoWindow = True
Proc1.Start()
If Not Proc1.WaitForExit(300) Then
Proc1.Kill()
End If
'INSERT RESULTS INTO LOGGEN_IN COLUMN
Dim msg As String = Proc1.StandardOutput.ReadToEnd
Dim idx As Integer = msg.LastIndexOf("\"c)
Dim user As String = msg.Substring(idx + 1)
Dim final As String = UCase(System.Text.RegularExpressions.Regex.Replace(user, "^ELP.*$", ""))
datagridView1.Rows(i).Cells(2).Value = final
Next
End Sub
Finally, here is my question:
To get the employee names I must use regex becuase the raw format is unacceptable.
raw format:
"Connecting to Registry of \ELPSC171698...
Users logged on locally:
ECHOSTAR\Jane.Doe"
format after applying:
'INSERT RESULTS INTO LOGGEN_IN COLUMN
Dim msg As String = Proc1.StandardOutput.ReadToEnd
Dim idx As Integer = msg.LastIndexOf("\"c)
Dim user As String = msg.Substring(idx + 1)
Dim final As String = UCase(System.Text.RegularExpressions.Regex.Replace(user, "^ELP.*$", ""))
datagridView1.Rows(i).Cells(2).Value = final
"PAULA.RODRIGUEZ"
Looks good, right? However, when the raw format has more than one associate, like so:
"Connecting to Registry of \ELPSC173068...
Users logged on locally:
ECHOSTAR\John.Doe
ECHOSTAR\Ben.Doe"
the code I have written will get me the last person in this list. In this case, I will get JOHN.DOE when I need to get BEN.DOE.
Now the question: How can I change this code:
'INSERT RESULTS INTO LOGGEN_IN COLUMN
Dim msg As String = Proc1.StandardOutput.ReadToEnd
Dim idx As Integer = msg.LastIndexOf("\"c)
Dim user As String = msg.Substring(idx + 1)
Dim final As String = UCase(System.Text.RegularExpressions.Regex.Replace(user, "^ELP.*$", ""))
datagridView1.Rows(i).Cells(2).Value = final
To get me the first person, "JOHN.DOE" from here:
"Connecting to Registry of \ELPSC173068...
Users logged on locally:
ECHOSTAR\John.Doe
ECHOSTAR\Ben.Doe"
I hope my question was clear and well constructed. Thank you.
Use more specific regex and a capture group to get multiple items.
Dim mc As MatchCollection = Regex.Matches("Users logged on locally: ECHOSTAR\John.Doe ECHOSTAR\Ben.Doe", "[\t ]+[a-z_0-9]+\\(?<n>[a-z_\.0-9]+)(([\t ])|($))", RegexOptions.ExplicitCapture Or RegexOptions.IgnoreCase Or RegexOptions.Multiline)
For Each m As Match In mc
Dim name As String = m.Groups("n").value
Next
if you just want the first one then...
If mc.Count >= 1 Then
Dim name As String = mc(0).Groups("n").Value
End If
Change
Dim idx As Integer = msg.LastIndexOf("\"c)
to
Dim idx As Integer = msg.IndexOf("\"c)
Alternatively consider this:
Assuming you've validated the string first.
Dim user As String = msg.Split({"\"c, " "c}, StringSplitOptions.RemoveEmptyEntries)(1) _
.Replace("."c, " "c).ToUpper
To leave the decimal in just remove .Replace("."c, " "c)

Pretty String Manipulation

I have the following string which I wish to extract parts from:
<FONT COLOR="GREEN">201 KAR 2:340.</FONT>
In this particular case, I wish to extract the numbers 201,2, and 340, which I will later use to concatenate to form another string:
http://www.lrc.state.ky.us/kar/201/002/340reg.htm
I have a solution, but it is not easily readable, and it seems rather clunky. It involves using the mid function. Here it is:
intTitle = CInt(Mid(strFontTag,
InStr(strFontTag, ">") + 1,
(InStr(strFontTag, "KAR") - InStr(strFontTag, ">"))
- 3))
I would like to know if perhaps there is a better way to approach this task. I realize I could make some descriptive variable names, like intPosOfEndOfOpeningFontTag to describe what the first InStr function does, but it still feels clunky to me.
Should I be using some sort of split function, or regex, or some more elegant way that I have not come across yet? I have been manipulating strings in this fashion for years, and I just feel there must be a better way. Thanks.
<FONT[^>]*>[^\d]*(\d+)[^\d]*(\d+):(\d+)[^\d]*</FONT>
The class
Imports System
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Xml
Imports System.Xml.Linq
Imports System.Linq
Public Class clsTester
'methods
Public Sub New()
End Sub
Public Function GetTitleUsingRegEx(ByVal fpath$) As XElement
'use this function if your input string is not a well-formed
Dim result As New XElement(<result/>)
Try
Dim q = Regex.Matches(File.ReadAllText(fpath), Me.titPattern1, RegexOptions.None)
For Each mt As Match In q
Dim t As New XElement(<title/>)
t.Add(New XAttribute("name", mt.Groups("name").Value))
t.Add(New XAttribute("num1", mt.Groups("id_1").Value))
t.Add(New XAttribute("num2", mt.Groups("id_2").Value))
t.Add(New XAttribute("num3", mt.Groups("id_3").Value))
t.Add(mt.Value)
result.Add(t)
Next mt
Return result
Catch ex As Exception
result.Add(<error><%= ex.ToString %></error>)
Return result
End Try
End Function
Public Function GetTitleUsingXDocument(ByVal fpath$) As XElement
'use this function if your input string is well-formed
Dim result As New XElement(<result/>)
Try
Dim q = XElement.Load(fpath).Descendants().Where(Function(c) Regex.IsMatch(c.Name.LocalName, "(?is)^font$")).Where(Function(c) Regex.IsMatch(c.Value, Me.titPattern2, RegexOptions.None))
For Each nd As XElement In q
Dim s = Regex.Match(nd.Value, Me.titPattern2, RegexOptions.None)
Dim t As New XElement(<title/>)
t.Add(New XAttribute("name", s.Groups("name").Value))
t.Add(New XAttribute("num1", s.Groups("id_1").Value))
t.Add(New XAttribute("num2", s.Groups("id_2").Value))
t.Add(New XAttribute("num3", s.Groups("id_3").Value))
t.Add(nd.Value)
result.Add(t)
Next nd
Return result
Catch ex As Exception
result.Add(<error><%= ex.ToString %></error>)
Return result
End Try
End Function
'fields
Private titPattern1$ = "(?is)(?<=<font[^<>]*>)(?<id_1>\d+)\s+(?<name>[a-z]+)\s+(?<id_2>\d+):(?<id_3>\d+)(?=\.?</font>)"
Private titPattern2$ = "(?is)^(?<id_1>\d+)\s+(?<name>[a-z]+)\s+(?<id_2>\d+):(?<id_3>\d+)\.?$"
End Class
The usage
Sub Main()
Dim y = New clsTester().GetTitleUsingRegEx("C:\test.htm")
If y.<error>.Count = 0 Then
Console.WriteLine(String.Format("Result from GetTitleUsingRegEx:{0}{1}", vbCrLf, y.ToString))
Else
Console.WriteLine(y...<error>.First().Value)
End If
Console.WriteLine("")
Dim z = New clsTester().GetTitleUsingXDocument("C:\test.htm")
If z.<error>.Count = 0 Then
Console.WriteLine(String.Format("Result from GetTitleUsingXDocument:{0}{1}", vbCrLf, z.ToString))
Else
Console.WriteLine(z...<error>.First().Value)
End If
Console.ReadLine()
End Sub
Hope this helps.
regex pattern: <FONT[^>]*>.*?(\d+).*?(\d+).*?(\d+).*?<\/FONT>
I think #Jean-François Corbett has it right.
Hide it away in a function and never look back
Change your code to this:
intTitle = GetCodesFromColorTag("<FONT COLOR="GREEN">201 KAR 2:340.</FONT>")
Create a new function:
Public Function GetCodesFromColorTag(FontTag as String) as Integer
Return CInt(Mid(FontTag, InStr(FontTag, ">") + 1,
(InStr(FontTag, "KAR") - InStr(FontTag, ">"))
- 3))
End Function