This is my first web scraping task. I have been tasked with scraping a website
It is a site that contains the names of lawyers in Denmark. My difficulty is that I can only retrieve names based on the particular name query i put in the search bar. Is there an online web tool I can use to scrape all the names that the website contains? I have used tools like Import.io with no success so far. I am super confused on how all of this works.
Please scroll down to UPDATE 2
The website enforces you to enter at least one search parameter, so you may loop through all items for Arbejdsområde list, making request for each of them. Here is the example, showing how that could be done in Excel VBA (open VBE, create standard module, paste the code and run Test()):
Option Explicit
Sub Test()
Dim sResponse As String
Dim oItems As Object
Dim vItem
Dim aData
Dim sContent As String
Dim lPage As Long
Dim i As Long
Dim j As Long
' Retrieve search page HTML content
XmlHttpRequest "GET", "http://www.advokatnoeglen.dk/", "", "", "", sResponse
' Extract work areas items
ExtractOptions sResponse, "ctl00$ContentPlaceHolder$Search$AreaSelect", oItems
oItems.Remove oItems.Keys()(0)
sContent = ""
' Process each work area item
For Each vItem In oItems.Items()
Debug.Print "Item [" & vItem & "]"
lPage = 0
' Process each results page
Do
Debug.Print vbTab & "Page [" & lPage & "]"
' Retrieve result page HTML content
XmlHttpRequest "GET", "http://www.advokatnoeglen.dk/sog.aspx?s=1&t=0&a=" & vItem & "&p=" & lPage, "", "", "", sResponse
' Extract result table
ParseResponse _
"<table\b[^>]*?id=""ctl00_ContentPlaceHolder_Grid""[^>]*>([\s\S]*?)</table>", _
sResponse, _
aData, _
False
' Store parsed table
sContent = sContent & aData(0)
Debug.Print vbTab & "Parsed " & Len(sContent)
lPage = lPage + 1
DoEvents
Loop Until InStr(sResponse, "<a class=""next""") = 0
Next
' Extract data from the whole content
ParseResponse _
"<tr.*?onclick=""location.href='([^']*)'"">\s*" & _
"<td[^>]*>\s*([\s\S]*?)\s*</td>\s*" & _
"<td[^>]*>\s*([\s\S]*?)\s*</td>\s*" & _
"<td[^>]*>\s*([\s\S]*?)\s*</td>\s*" & _
"</tr>", _
sContent, _
aData, _
False
' Rebuild nested arrays to 2d array for output
aData = Denestify(aData)
' Decode HTML
For i = 1 To UBound(aData, 1)
For j = 2 To 4
aData(i, j) = GetInnerText((aData(i, j)))
Next
Next
' Output
With ThisWorkbook.Sheets(1)
.Cells.Delete
Output2DArray .Cells(1, 1), aData
.Columns.AutoFit
.Rows.AutoFit
End With
MsgBox "Completed"
End Sub
Sub XmlHttpRequest(sMethod, sUrl, aSetHeaders, sFormData, sRespHeaders, sRespText)
Dim aHeader
'With CreateObject("MSXML2.ServerXMLHTTP")
'.SetOption 2, 13056 ' SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS
With CreateObject("MSXML2.XMLHTTP")
.Open sMethod, sUrl, False ' , "u051772", "fy17janr"
If IsArray(aSetHeaders) Then
For Each aHeader In aSetHeaders
.SetRequestHeader aHeader(0), aHeader(1)
Next
End If
.Send (sFormData)
sRespHeaders = .GetAllResponseHeaders
sRespText = .ResponseText
End With
End Sub
Sub ExtractOptions(sContent As String, ByVal sName As String, oOptions As Object)
Dim aTmp0
Dim vItem
' Escape RegEx special characters
For Each vItem In Array("\", "*", "+", "?", "^", "$", ".", "[", "]", "{", "}", "(", ")", "|", "/")
sName = Replace(sName, vItem, "\" & vItem)
Next
' Extract the whole <select> for parameter
ParseResponse "<select[^>]* name=""?" & sName & """?[^>]*>[^<]*((?:<option[^>]*>[^<]*</option>[^<]*)+)[^<]*</[^>]*>", sContent, aTmp0, False
' Extract each parameter <option>
ParseResponse "<option[^>]*value=(""[^""]*""|[^\s>]*)[^>]*>([^<]*)</option>", (aTmp0(0)), aTmp0, False
' Put each parameter and value into dictionary
Set oOptions = CreateObject("Scripting.Dictionary")
For Each vItem In aTmp0
oOptions(GetInnerText((vItem(1)))) = GetInnerText(Replace(vItem(0), """", ""))
Next
End Sub
Sub ParseResponse(sPattern, sResponse, aData, Optional bAppend As Boolean = True, Optional bGlobal = True, Optional bMultiLine = True, Optional bIgnoreCase = True)
Dim oMatch
Dim aTmp0()
Dim sSubMatch
If Not (IsArray(aData) And bAppend) Then aData = Array()
With CreateObject("VBScript.RegExp")
.Global = bGlobal
.MultiLine = bMultiLine
.IgnoreCase = bIgnoreCase
.Pattern = sPattern
For Each oMatch In .Execute(sResponse)
If oMatch.SubMatches.Count = 1 Then
PushItem aData, oMatch.SubMatches(0)
Else
aTmp0 = Array()
For Each sSubMatch In oMatch.SubMatches
PushItem aTmp0, sSubMatch
Next
PushItem aData, aTmp0
End If
Next
End With
End Sub
Sub PushItem(aData, vItem, Optional bAppend As Boolean = True)
If Not (IsArray(aData) And bAppend) Then aData = Array()
ReDim Preserve aData(UBound(aData) + 1)
aData(UBound(aData)) = vItem
End Sub
Function GetInnerText(sText As String) As String
Static oHtmlfile As Object
Static oDiv As Object
If oHtmlfile Is Nothing Then
Set oHtmlfile = CreateObject("htmlfile")
oHtmlfile.Open
Set oDiv = oHtmlfile.createElement("div")
End If
oDiv.innerHTML = sText
GetInnerText = oDiv.innerText
End Function
Function Denestify(aRows)
Dim aData()
Dim aItems()
Dim i As Long
Dim j As Long
If UBound(aRows) = -1 Then Exit Function
ReDim aData(1 To UBound(aRows) + 1, 1 To 1)
For j = 0 To UBound(aRows)
If IsArray(aRows(j)) Then
aItems = aRows(j)
For i = 0 To UBound(aItems)
If i + 1 > UBound(aData, 2) Then ReDim Preserve aData(1 To UBound(aRows) + 1, 1 To i + 1)
aData(j + 1, i + 1) = aItems(i)
Next
Else
aData(j + 1, 1) = aRows(j)
End If
Next
Denestify = aData
End Function
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
It takes few minutes to retrieve all data for the first time (after that when launched again all requests are loaded from the cache that makes process significantly faster, to get a latest data from the server you need to clean up the cache in IE settings). The output for me is as follows:
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.
BTW there are another answers using the similar approach: 1, 2, 3 and 4.
UPDATE
The above suggested scraping is based on parsing search results filtered by Arbejdsområde parameter, and as it turned out, actually returned results are inaccurate. Those lawyers, which have multiply Arbejdsområder are present multiply times in results, and which have empty Arbejdsområder are not in results at all.
Another parameter instead of Arbejdsområde, that can be used for such scraping is Retskreds. All lawyers records contain address, and only single address, so results are full and don't contain duplicates. Note, one lawyer can relate to several offices, so that will be several records in results.
There is the code that allows to scrape detailed info for each entry within loop:
Option Explicit
Sub Test()
Dim sResponse As String
Dim oItems As Object
Dim vKey
Dim sItem As String
Dim aTmp
Dim aData
Dim lPage As Long
Dim i As Long
Dim j As Long
' Retrieve search page HTML content
XmlHttpRequest "GET", "http://www.advokatnoeglen.dk/", "", "", "", sResponse
' Extract Retskreds items
ExtractOptions sResponse, "ctl00$ContentPlaceHolder$Search$CourtSelect", oItems
oItems.Remove oItems.Keys()(0)
i = 0
' Process each Retskreds item
For Each vKey In oItems
sItem = oItems(vKey)
Debug.Print "Area " & sItem & " " & vKey
lPage = 0
' Process each results page
Do
Debug.Print vbTab & "Page " & lPage
' Retrieve results page
XmlHttpRequest "GET", "http://www.advokatnoeglen.dk/sog.aspx?s=1&t=0&c=" & sItem & "&p=" & lPage, "", "", "", sResponse
' Extract table
ParseResponse _
"<table\b[^>]*?id=""ctl00_ContentPlaceHolder_Grid""[^>]*>([\s\S]*?)</table>", _
sResponse, _
aTmp, _
False
' Extract data from the table
ParseResponse _
"<tr.*?onclick=""location.href='([^']*)'"">\s*" & _
"<td[^>]*>\s*([\s\S]*?)\s*</td>\s*" & _
"<td[^>]*>\s*([\s\S]*?)\s*</td>\s*" & _
"<td[^>]*>\s*([\s\S]*?)\s*</td>\s*" & _
"</tr>", _
aTmp(0), _
aData, _
True
' Add Retskreds name
For i = i To UBound(aData)
aTmp = aData(i)
PushItem aTmp, vKey
aData(i) = aTmp
Next
Debug.Print vbTab & "Parsed " & UBound(aData)
lPage = lPage + 1
DoEvents
Loop Until InStr(sResponse, "<a class=""next""") = 0
Next
' Retrieve detailed info for each entry
For i = 0 To UBound(aData)
aTmp = aData(i)
' Retrieve details page
aTmp(0) = "http://www.advokatnoeglen.dk" & aTmp(0)
' Extract details
XmlHttpRequest "GET", aTmp(0), "", "", "", sResponse
ParseResponse _
DecodeUriComponent( _
"Arbejdsomr%C3%A5der\: [\s\S]*?</h2>[\s\S]*?" & _
"Beskikkelses%C3%A5r\: ([^<]*)[\s\S]*?" & _
"F%C3%B8dsels%C3%A5r\: ([^<]*)[\s\S]*?" & _
"M%C3%B8deret for landsret\: ([^<]*)[\s\S]*?" & _
"M%C3%B8deret for h%C3%B8jesteret\: ([^<]*)[\s\S]*?" & _
"E-mail\: [\s\S]*?href='\/email\.aspx\?e\=(.*?)'[\s\S]*?" & _
"Mobiltlf\.\: ([\d\(\)\-+ ]*?)\s*<"), _
sResponse, _
aTmp, _
True, _
False
aTmp(9) = StrReverse(aTmp(9))
aData(i) = aTmp
Debug.Print vbTab & "Details " & i
DoEvents
Next
' Rebuild nested arrays to 2d array for output
aData = Denestify(aData)
' Decode HTML
For i = 1 To UBound(aData, 1)
For j = 2 To 4
aData(i, j) = Trim(Replace(GetInnerText((aData(i, j))), vbCrLf, ""))
Next
Next
' Output
With ThisWorkbook.Sheets(1)
.Cells.Delete
OutputArray .Cells(1, 1), _
Array("URL", _
"Navn", _
"Firma", _
DecodeUriComponent("Arbejdsomr%C3%A5der"), _
DecodeUriComponent("Retskreds"), _
DecodeUriComponent("Beskikkelses%C3%A5r"), _
DecodeUriComponent("F%C3%B8dsels%C3%A5r"), _
DecodeUriComponent("M%C3%B8deret for landsret"), _
DecodeUriComponent("M%C3%B8deret for h%C3%B8jesteret"), _
"E-mail", _
"Mobiltlf." _
)
Output2DArray .Cells(2, 1), aData
.Columns.AutoFit
.Rows.AutoFit
End With
MsgBox "Completed"
End Sub
Sub XmlHttpRequest(sMethod, sUrl, aSetHeaders, sFormData, sRespHeaders, sRespText)
Dim aHeader
'With CreateObject("MSXML2.ServerXMLHTTP")
'.SetOption 2, 13056 ' SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS
With CreateObject("MSXML2.XMLHTTP")
.Open sMethod, sUrl, False
If IsArray(aSetHeaders) Then
For Each aHeader In aSetHeaders
.SetRequestHeader aHeader(0), aHeader(1)
Next
End If
.Send (sFormData)
sRespHeaders = .GetAllResponseHeaders
sRespText = .ResponseText
End With
End Sub
Sub ExtractOptions(sContent As String, ByVal sName As String, oOptions As Object)
Dim aTmp0
Dim vItem
' Escape RegEx special characters
For Each vItem In Array("\", "*", "+", "?", "^", "$", ".", "[", "]", "{", "}", "(", ")", "|", "/")
sName = Replace(sName, vItem, "\" & vItem)
Next
' Extract the whole <select> for parameter
ParseResponse "<select[^>]* name=""?" & sName & """?[^>]*>[^<]*((?:<option[^>]*>[^<]*</option>[^<]*)+)[^<]*</[^>]*>", sContent, aTmp0, False
' Extract each parameter <option>
ParseResponse "<option[^>]*value=(""[^""]*""|[^\s>]*)[^>]*>([^<]*)</option>", (aTmp0(0)), aTmp0, False
' Put each parameter and value into dictionary
Set oOptions = CreateObject("Scripting.Dictionary")
For Each vItem In aTmp0
oOptions(GetInnerText((vItem(1)))) = GetInnerText(Replace(vItem(0), """", ""))
Next
End Sub
Sub ParseResponse(sPattern, sResponse, aData, Optional bAppend As Boolean = True, Optional bNestSubMatches = True, Optional bGlobal = True, Optional bMultiLine = True, Optional bIgnoreCase = True)
Dim oMatch
Dim aTmp0()
Dim sSubMatch
If Not (IsArray(aData) And bAppend) Then aData = Array()
With CreateObject("VBScript.RegExp")
.Global = bGlobal
.MultiLine = bMultiLine
.IgnoreCase = bIgnoreCase
.Pattern = sPattern
For Each oMatch In .Execute(sResponse)
If oMatch.SubMatches.Count = 1 Then
PushItem aData, oMatch.SubMatches(0)
Else
If bNestSubMatches Then
aTmp0 = Array()
For Each sSubMatch In oMatch.SubMatches
PushItem aTmp0, sSubMatch
Next
PushItem aData, aTmp0
Else
For Each sSubMatch In oMatch.SubMatches
PushItem aData, sSubMatch
Next
End If
End If
Next
End With
End Sub
Sub PushItem(aData, vItem, Optional bAppend As Boolean = True)
If Not (IsArray(aData) And bAppend) Then aData = Array()
ReDim Preserve aData(UBound(aData) + 1)
aData(UBound(aData)) = vItem
End Sub
Function DecodeUriComponent(sEncoded As String) As String
Static objHtmlfile As Object
If objHtmlfile Is Nothing Then
Set objHtmlfile = CreateObject("htmlfile")
objHtmlfile.parentWindow.execScript "function decode(s) {return decodeURIComponent(s)}", "jscript"
End If
DecodeUriComponent = objHtmlfile.parentWindow.decode(sEncoded)
End Function
Function GetInnerText(sText As String) As String
Static oHtmlfile As Object
Static oDiv As Object
If oHtmlfile Is Nothing Then
Set oHtmlfile = CreateObject("htmlfile")
oHtmlfile.Open
Set oDiv = oHtmlfile.createElement("div")
End If
oDiv.innerHTML = sText
GetInnerText = oDiv.innerText
End Function
Function Denestify(aRows)
Dim aData()
Dim aItems()
Dim i As Long
Dim j As Long
If UBound(aRows) = -1 Then Exit Function
ReDim aData(1 To UBound(aRows) + 1, 1 To 1)
For j = 0 To UBound(aRows)
If IsArray(aRows(j)) Then
aItems = aRows(j)
For i = 0 To UBound(aItems)
If i + 1 > UBound(aData, 2) Then ReDim Preserve aData(1 To UBound(aRows) + 1, 1 To i + 1)
aData(j + 1, i + 1) = aItems(i)
Next
Else
aData(j + 1, 1) = aRows(j)
End If
Next
Denestify = aData
End Function
Sub OutputArray(oDstRng As Range, aCells As Variant, Optional sFormat As String = "#")
With oDstRng
.Parent.Select
With .Resize(1, UBound(aCells) - LBound(aCells) + 1)
.NumberFormat = sFormat
.Value = aCells
End With
End With
End Sub
Sub Output2DArray(oDstRng As Range, aCells As Variant, Optional sFormat As String = "#")
With oDstRng
.Parent.Select
With .Resize( _
UBound(aCells, 1) - LBound(aCells, 1) + 1, _
UBound(aCells, 2) - LBound(aCells, 2) + 1)
.NumberFormat = sFormat
.Value = aCells
End With
End With
End Sub
There are 4896 entries total for 4689 lawyers:
UPDATE 2
Seems to get complete list you may just make search with set (space) as Firma parameter: http://www.advokatnoeglen.dk/sog.aspx?s=1&t=0&firm=%20, there are 6511 entries at the moment. The Sub Test() code for parse that results should be changed then as shown below:
Option Explicit
Sub Test()
Dim sResponse As String
Dim aTmp
Dim aData
Dim lPage As Long
Dim i As Long
Dim j As Long
lPage = 0
' Process each results page
Do
Debug.Print vbTab & "Page " & lPage
' Retrieve results page
XmlHttpRequest "GET", "http://www.advokatnoeglen.dk/sog.aspx?s=1&t=0&firm=%20&p=" & lPage, "", "", "", sResponse
' Extract table
ParseResponse _
"<table\b[^>]*?id=""ContentPlaceHolder_Grid""[^>]*>([\s\S]*?)</table>", _
sResponse, _
aTmp, _
False
' Extract data from the table
ParseResponse _
"<tr.*?onclick=""location.href='(.*?)'"">\s*" & _
"<td[^>]*>\s*([\s\S]*?)\s*</td>\s*" & _
"<td[^>]*>\s*([\s\S]*?)\s*</td>\s*" & _
"<td[^>]*>\s*([\s\S]*?)\s*</td>\s*" & _
"</tr>", _
aTmp(0), _
aData, _
True
Debug.Print vbTab & "Parsed " & (UBound(aData) + 1)
lPage = lPage + 1
DoEvents
Loop Until InStr(sResponse, "<a class=""next""") = 0
' Retrieve detailed info for each entry
For i = 0 To UBound(aData)
aTmp = aData(i)
' Retrieve details page
aTmp(0) = "http://www.advokatnoeglen.dk" & aTmp(0)
' Extract details
Do
XmlHttpRequest "GET", aTmp(0), "", "", "", sResponse
If InStr(sResponse, "<title>Runtime Error</title>") = 0 Then Exit Do
DoEvents
Loop
ParseResponse _
DecodeUriComponent( _
"Arbejdsomr%C3%A5der\: [\s\S]*?</h2>[\s\S]*?" & _
"Beskikkelses%C3%A5r\: ([^<]*)[\s\S]*?" & _
"(:?F%C3%B8dsels%C3%A5r\: ([^<]*)[\s\S]*?)?" & _
"M%C3%B8deret for landsret\: ([^<]*)[\s\S]*?" & _
"M%C3%B8deret for h%C3%B8jesteret\: ([^<]*)[\s\S]*?" & _
"(:?E-mail [\s\S]*?href='\/email\.aspx\?e\=(.*?)'[\s\S]*?)?" & _
"Mobiltlf\.\: ([\d\(\)\-+ ]*?)\s*<"), _
sResponse, _
aTmp, _
True, _
False
aTmp(8) = StrReverse(aTmp(8))
aData(i) = aTmp
Debug.Print vbTab & "Details " & i
DoEvents
Next
' Rebuild nested arrays to 2d array for output
aData = Denestify(aData)
' Decode HTML
For i = 1 To UBound(aData, 1)
For j = 2 To 4
aData(i, j) = Trim(Replace(GetInnerText((aData(i, j))), vbCrLf, ""))
Next
Next
' Output
With ThisWorkbook.Sheets(1)
.Cells.Delete
OutputArray .Cells(1, 1), _
Array("URL", _
"Navn", _
"Firma", _
DecodeUriComponent("Arbejdsomr%C3%A5der"), _
DecodeUriComponent("Beskikkelses%C3%A5r"), _
DecodeUriComponent("F%C3%B8dsels%C3%A5r"), _
DecodeUriComponent("M%C3%B8deret for landsret"), _
DecodeUriComponent("M%C3%B8deret for h%C3%B8jesteret"), _
"E-mail", _
"Mobiltlf." _
)
Output2DArray .Cells(2, 1), aData
.Columns.AutoFit
.Rows.AutoFit
End With
MsgBox "Completed"
End Sub
I have some code in c# that was converted over from vb.net. I am getting this error on the codebehind page of an aspx page. One of the errors reads
Cannot apply indexing to an expression of type 'dtInventory_v10_r1'
the error that I am receiving from visual studio reads this however
Argument missing
The line of code that this references is as follows:
objInv = objMan.GetInventoryObject(mInventory_ID, , , true);
The GetInventoryObject is written in VB and looks like this
Public Function GetInventoryObject(ByVal vInventory_ID As Integer, _
Optional ByVal vVIN As String = "", _
Optional ByVal vSelectedTrim As String = "", _
Optional ByVal vIncludeDetail As Boolean = False, _
Optional ByVal vIncludeValuations As Boolean = False, _
Optional ByVal vIncludeEquipment As Boolean = False, _
Optional ByVal vIncludeTitle As Boolean = False, _
Optional ByVal vIncludeBuyersGuide As Boolean = False, _
Optional ByVal vIncludeImages As Boolean = False, _
Optional ByVal vIncludeFinance As Boolean = False, _
Optional ByVal vIncludeExpenses As Boolean = False, _
Optional ByVal vIncludeTransactions As Boolean = False, _
Optional ByVal vIncludeInternetMarketing As Boolean = False, _
Optional ByVal vIncludeFlags As Boolean = False, _
Optional ByVal vIncludeSupportingFiles As Boolean = False, _
Optional ByVal vYearModel As Integer = 0, _
Optional ByVal vMake As String = "", _
Optional ByVal vModel As String = "", _
Optional ByVal vBodyStyle As String = "", _
Optional ByVal vExtTrim As String = "", _
Optional ByVal vExtColor As String = "", _
Optional ByVal vIntColor As String = "", _
Optional ByVal vTransmission As String = "", _
Optional ByVal vDriveType As String = "", _
Optional ByVal vEngine As String = "", _
Optional ByVal vWeight As Integer = 0, _
Optional ByVal vFuelType As String = "", _
Optional ByVal vLot_ID As Integer = 0
) As Inventory
Dim strParameters As String = ""
Dim dsTempDataSet As DataSet
Dim strXML As String = ""
If vLot_ID = 0 Then
'if an autosave occurs and a lot is not enterd
'pass in the uses branch
vLot_ID = mobjSecurity.Branch_ID
End If
strParameters = "#SessionGUID='" & mobjSecurity.SecuritySession & "', "
strParameters &= "#Inst_ID=" & mobjSecurity.Inst_ID.ToString & ", "
strParameters += "#Inventory_ID=" & vInventory_ID.ToString & ", "
strParameters += "#VIN='" & vVIN.ToString & "', "
strParameters += "#IncludeDetail=" & mobjFormat.FormatBooleanToInteger(vIncludeDetail) & ", "
strParameters += "#IncludeValuations=" & mobjFormat.FormatBooleanToInteger(vIncludeValuations) & ", "
strParameters += "#IncludeEquipment=" & mobjFormat.FormatBooleanToInteger(vIncludeEquipment) & ","
strParameters += "#IncludeTitle=" & mobjFormat.FormatBooleanToInteger(vIncludeTitle) & ", "
strParameters += "#IncludeBuyersGuide=" & mobjFormat.FormatBooleanToInteger(vIncludeBuyersGuide) & ", "
strParameters += "#IncludeImages=" & mobjFormat.FormatBooleanToInteger(vIncludeImages) & ", "
strParameters += "#IncludeFinance=" & mobjFormat.FormatBooleanToInteger(vIncludeFinance) & ", "
strParameters += "#IncludeExpenses=" & mobjFormat.FormatBooleanToInteger(vIncludeExpenses) & ", "
strParameters += "#IncludeTransactions=" & mobjFormat.FormatBooleanToInteger(vIncludeTransactions) & ", "
strParameters += "#IncludeInternetMarketing=" & mobjFormat.FormatBooleanToInteger(vIncludeInternetMarketing) & ", "
strParameters += "#IncludeFlags=" & mobjFormat.FormatBooleanToInteger(vIncludeFlags) & ", "
strParameters += "#IncludeSupportingFiles=" & mobjFormat.FormatBooleanToInteger(vIncludeSupportingFiles) & ", "
strParameters += "#YearModel=" & vYearModel.ToString & ", "
strParameters += "#Make='" & vMake.ToString & "', "
strParameters += "#Model='" & vModel.ToString & "', "
strParameters += "#BodyStyle='" & vBodyStyle.ToString & "', "
strParameters += "#ExtTrim='" & vExtTrim.ToString & "', "
strParameters += "#ExtColor='" & vExtColor.ToString & "', "
strParameters += "#IntColor='" & vIntColor.ToString & "', "
strParameters += "#Transmission='" & vTransmission.ToString & "', "
strParameters += "#DriveType='" & vDriveType.ToString & "', "
strParameters += "#Engine='" & vEngine.ToString & "', "
strParameters += "#Weight=" & vWeight.ToString & ", "
strParameters += "#FuelType='" & vFuelType.ToString & "', "
strParameters += "#Lot_ID=" & vLot_ID.ToString & " "
dsTempDataSet = Fetch("pr_Inventory_v10_FetchObject_r1", strParameters, mobjSecurity.SQLDatabase)
Dim dsComplete As New DataSet
Dim objExport As New dtDataTools_v10_r1.ExportData
Dim iTable As Integer = 0
Dim sDataTableName As String = ""
Dim sRelatedTableName As String = ""
Dim sRelatedFieldName As String = ""
'-- Loop all returned tables
For iTable = 0 To dsTempDataSet.Tables.Count - 1
If sDataTableName = "" Then
'-- Make sure we have rows
If dsTempDataSet.Tables(iTable).Rows.Count > 0 Then
'-- Read first column...
If dsTempDataSet.Tables(iTable).Columns(0).ColumnName.ToLower = "datatablename" Then
'-- Get table info
sDataTableName = dsTempDataSet.Tables(iTable).Rows(0).Item("datatablename")
sRelatedTableName = dsTempDataSet.Tables(iTable).Rows(0).Item("RelatedTableName")
sRelatedFieldName = dsTempDataSet.Tables(iTable).Rows(0).Item("RelatedFieldName")
End If
End If
Else
'-- Name and store the table
dsTempDataSet.Tables(iTable).TableName = sDataTableName
dsComplete.Tables.Add(dsTempDataSet.Tables(iTable).Copy)
Try
'-- Add Relationship?
If sRelatedTableName.Trim <> "" Then
With dsComplete
.Relations.Add("rel_" & sDataTableName, _
.Tables(sRelatedTableName).Columns(sRelatedFieldName), _
.Tables(sDataTableName).Columns(sRelatedFieldName))
End With
End If
Catch ex As Exception
End Try
sDataTableName = "" '-- Reset
sRelatedTableName = ""
sRelatedFieldName = ""
End If
Next
'-- Generate and strip the XML
strXML = objExport.ConvertDatasetToXML(dsComplete.Copy, "dealtrace", MappingType.Attribute, 1)
'-- Load XML into Report object
Return LoadInventory_XML(strXML)
End Function
The mInventory_ID is an int variable and is declared like this
protected Int32 mInventory_ID = 0;
I am not sure how to fix the error that I am getting I have tried to change the parenthesis to square brackets to no avail. I have tried adding extra commas for the remaining declarations in the function but that also yielded the same errors.
Are there any suggestions on what may be causing this error and how to fix this
Thank you in advance
These are optional parameters, and should be called with following syntax
objInv = objMan.GetInventoryObject(vVIN=mInventory_ID, vIncludeValuations=true);
Basically you explicitly name parameters default values of which you would like to override. Skipping param with , , is indeed incorrect syntax.
I need to know how to send a stamped pdf to receiptants for digital signing. The pdf is stamped using itextsharp
do I need an envelope id for the api? How do I attach the stamped pdf for sending using docusign?
Function
Private pdfFormFileName As String = "myAcrobatFormFile.pdf"
Sub Print_Click(ByVal sender As Object, ByVal e As CommandEventArgs)
Dim sUniqueKey As String
Dim dr As OdbcDataReader
Dim sql As String
Dim reader As PdfReader
Dim sFileName As String = ""
Dim sArray As Array
sUniqueKey = e.CommandArgument
sArray = sUniqueKey.Split(",")
sql = "select "
sql += "name,"
sql += "id"
sql += " from table"
sql += " where key1=" & sArray(0)
sql += " and key2=" & sArray(1)
oFnc.OpenODBC()
selectCommand = New OdbcCommand(sql, oFnc.connWeb)
dr = selectCommand.ExecuteReader
If dr.Read Then
reader = New PdfReader(server.mappath(pdfFormFileName))
sFileName = "data/" & oFnc.GetTimeStamp & "displayForm.pdf"
Dim stamper As PdfStamper = New PdfStamper(reader, New System.IO.FileStream(Server.MapPath(sFileName), FileMode.Create))
Dim fields As AcroFields
fields = stamper.AcroFields
With fields
.SetField("txtName", Left(dr("name"), 20))
.SetField("txtId", dr("id")
End With
stamper.FormFlattening = True
stamper.Close()
End If
dr.Close()
oFnc.CloseODBC()
End Sub
How to send this xml
<?xml version="1.0" encoding="UTF-8"?>
<envelopeDefinition
xmlns="http://www.docusign.com/restapi"xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<emailBlurb>Annual contract</emailBlurb>
<emailSubject>API Call for adding signature request to document and
sending</emailSubject>
<status>sent</status>
<documents>
<document>
<documentId>1</documentId>
<name>myAcrobatFormFile.pdf</name>
</document>
</documents>
<recipients>
<signers>
<signer>
<recipientId>2</recipientId>
<email>abc#gmail.com</email>
<name>Bob Smith</name>
</signer>
</signers>
</recipients>
</envelopeDefinition>
The DocuSign API Walkthroughs that you have found are great examples of how to do this, and the API Explorer is another great tool that shows you how the REST calls are made. Both of these can be found on the API Tools page in the Developer Center:
https://www.docusign.com/developer-center/quick-start/api-explorer
The API Explorer allows you to make any API call without writing any code. You just enter your credentials at the top of the page, select which call you want to make, fill out parameters (if needed), and hit the TRY IT button.
Unfortunately the API Walkthroughs do not have Visual Basic examples. However there are C# examples (another .NET technology), more particularly this example for requesting a signature on a local file:
http://iodocs.docusign.com/APIWalkthrough/requestSignatureFromDocument
Sub login_click(ByVal sender As Object, ByVal e As System.EventArgs)
'Dim oClient = New WebClient
Dim sUrl As String = "https://demo.docusign.net/restapi/v1/login_information?api_password=true&include_account_id_guid=true&login_settings=all"
Dim sEmail As String = "abc#gmail.com"
Dim sPassword As String = "mypassword"
Dim sIntegratorKey As String = "myintegratorkey"
Dim sDocumentName As String = "mypdfdocument.pdf"
Dim sContentType As String = "application/pdf"
Dim oRequest As HttpWebRequest
oRequest = initializeRequest(sUrl, "GET", "", sEmail, sPassword, sIntegratorKey)
Dim oResponse As HttpWebResponse = oRequest.GetResponse
Dim baseURL As String = ""
Dim oStreamReader As StreamReader = New StreamReader(oResponse.GetResponseStream)
Dim sXML As String = oStreamReader.ReadToEnd
baseURL = parseDataFromResponse(sXML, "baseUrl")
Dim sXmlBody As String
sXmlBody = "<envelopeDefinition xmlns='http://www.docusign.com/restapi'>" & _
"<emailSubject>DocuSign API</emailSubject>" & _
"<status>sent</status>" & _
"<documents>" & _
"<document>" & _
"<documentId>1</documentId>" & _
"<name>" & sDocumentName & "</name>" & _
"</document>" & _
"</documents>" & _
"<recipients>" & _
"<signers>" & _
"<signer>" & _
"<recipientId>1</recipientId>" & _
"<email>jsmith#abc.com</email>" & _
"<name>John Smith</name>" & _
"<tabs>" & _
"<signHereTabs>" & _
"<signHere>" & _
"<xPosition>100</xPosition>" & _
"<yPosition>100</yPosition>" & _
"<documentId>1</documentId>" & _
"<pageNumber>1</pageNumber>" & _
"</signHere>" & _
"</signHereTabs>" & _
"</tabs>" & _
"</signer>" & _
"</signers>" & _
"</recipients>" & _
"</envelopeDefinition>"
sUrl = baseURL & "/envelopes"
oRequest = initializeRequest(sUrl, "POST", "", sEmail, sPassword, sIntegratorKey)
configureMultiPartFormDataRequest(oRequest, sXmlBody, sDocumentName, sContentType)
Dim sMessage As String
sMessage = getResponseBody(oRequest)
MsgBox(sMessage)
'Dim sUri As String = parseDataFromResponse(sXML, "uri")
End Sub
Function getResponseBody(ByRef oRequest As HttpWebRequest) As String
Dim oResponse As HttpWebResponse = oRequest.GetResponse
Dim oStreamReader As StreamReader = New StreamReader(oResponse.GetResponseStream)
Dim sResponseString As String = oStreamReader.ReadToEnd
Return (sResponseString)
End Function
Sub configureMultiPartFormDataRequest(ByRef oRequest As HttpWebRequest, sXmlBody As String, sDocumentName As String, sContentType As String)
oRequest.ContentType = "multipart/form-data; boundary=BOUNDARY"
Dim sRequestBodyStart As String = "\r\n\r\n--BOUNDARY\r\n" & _
"Content-Type: application/xml\r\n" & _
"Content-Disposition: form-data\r\n" & _
"\r\n" & _
sXmlBody & "\r\n\r\n--BOUNDARY\r\n" & _
"Content-Type: " & sContentType & "\r\n" & _
"Content-Disposition: file; filename='" & sDocumentName & "'; documentId=1\r\n" & _
"\r\n"
Dim sRequestBodyEnd As String = "\r\n--BOUNDARY--\r\n\r\n"
Dim oFileStream As FileStream = File.OpenRead(Server.MapPath(sDocumentName))
Dim bodyStart As Byte() = System.Text.Encoding.UTF8.GetBytes(sRequestBodyStart.ToString)
Dim bodyEnd As Byte() = System.Text.Encoding.UTF8.GetBytes(sRequestBodyEnd.ToString)
Dim oDataStream As Stream = oRequest.GetRequestStream
oDataStream.Write(bodyStart, 0, sRequestBodyStart.ToString.Length())
Dim buffer(4096) As Byte
Dim iLen As Integer = 0
iLen = oFileStream.Read(buffer, 0, 4096)
Do While iLen > 0
oDataStream.Write(buffer, 0, iLen)
iLen = oFileStream.Read(buffer, 0, 4096)
Loop
oDataStream.Write(bodyEnd, 0, sRequestBodyEnd.ToString.Length())
oDataStream.Close()
End Sub
Function initializeRequest(sUrl As String, sMethod As String, sBody As String, sEmail As String, sPassword As String, sIntegratorKey As String) As HttpWebRequest
Dim oRequest As HttpWebRequest
oRequest = WebRequest.Create(sUrl)
oRequest.KeepAlive = False
oRequest.Method = sMethod
AddRequestHeaders(oRequest, sEmail, sPassword, sIntegratorKey)
If sBody <> "" Then
AddRequestBody(oRequest, sBody)
End If
Return (oRequest)
End Function
Sub AddRequestHeaders(ByRef oRequest As HttpWebRequest, sEmail As String, sPassword As String, sIntegratorKey As String)
oRequest.Headers.Add("X-DocuSign-Authentication",
String.Format("<DocuSignCredentials><Username>{0}</Username><Password>{1}</Password><IntegratorKey>{2}</IntegratorKey></DocuSignCredentials>", sEmail, sPassword, sIntegratorKey))
oRequest.Accept = "application/xml"
oRequest.ContentType = "application/xml"
End Sub
Sub addRequestBody(ByRef oRequest As HttpWebRequest, sRequestBody As String)
Dim body As Byte() = System.Text.Encoding.UTF8.GetBytes(sRequestBody)
Dim oDataStream As Stream = oRequest.GetRequestStream
oDataStream.Write(body, 0, sRequestBody.Length)
oDataStream.Close()
End Sub
Function parseDataFromResponse(sXML As String, sSearchToken As String) As String
Dim oXmlReader As XmlReader = XmlReader.Create(New StringReader(sXML))
Do While oXmlReader.Read()
If oXmlReader.NodeType = XmlNodeType.Element And oXmlReader.Name = sSearchToken Then
Return oXmlReader.ReadString()
End If
Loop
Return ""
End Function
could you please help me find the reason of the mystery I've found?
In the below code, I create a DataTable and filter it. When I use filter1, everything works as expected.
When I use filter2, everything works as expected only if the SubsectionAmount variable is less than 10.
As soon as I set SubsectionAmount=10, the dr2 array returns Nothing.
I can't find what is wrong. Here is the code:
Imports System.Data
Partial Class FilterTest
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Call FilterTable()
End Sub
Sub FilterTable()
Dim dtSubsections As New DataTable
Dim SectionID As Integer, SubsectionID As Integer
Dim SubsectionAmount As Integer
Dim filter1 As String, filter2 As String
Dim rowID As Integer
Dim dr1() As DataRow, dr2() As DataRow
With dtSubsections
.Columns.Add("Section")
.Columns.Add("Subsection")
.Columns.Add("FieldString")
SectionID = 1
SubsectionAmount = 10 '9
For SubsectionID = 1 To SubsectionAmount
.Rows.Add(SectionID, SubsectionID, "abcd" & CStr(SubsectionID))
Next SubsectionID
For rowID = 0 To .Rows.Count - 1
Response.Write(.Rows(rowID).Item(0).ToString & " " _
& .Rows(rowID).Item(1).ToString & " " _
& .Rows(rowID).Item(2).ToString & "<BR>")
Next
SubsectionID = 1
filter1 = "Section=" & SectionID & " AND " & "Subsection=" & SubsectionID
filter2 = "Section=" & SectionID & " AND " & "Subsection=" & SubsectionID + 1
dr1 = .Select(filter1)
dr2 = .Select(filter2)
Response.Write(dr1.Length & "<BR>")
Response.Write(dr2.Length & "<BR>")
If dr1.Length > 0 Then
Response.Write(dr1(0).Item("FieldString").ToString & "<BR>")
End If
If dr2.Length > 0 Then
Response.Write(dr2(0).Item("FieldString").ToString & "<BR>")
End If
End With
End Sub
End Class
The line
"Section=" & SectionID & " AND " & "Subsection=" & SubsectionID + 1
looks dodgy to me (?)
Consider this snippet of code:
var i = 2;
string j = "Hello " + i + 1;
when you print j you will get "Hello21" and not "Hello3". The + operator applied on a string will accept any object on the right-hand side and uses them by calling ToString() on the object, hence making your int effectively a string. Now, I assume that in VB.Net it is quite similar, which may not be what you want.
Update
Apparently VB.Net does things differently, so happily ignore...
change your column add statements to the following so it does the comparisons correctly.
.Columns.Add("Section", GetType(Integer))
.Columns.Add("Subsection", GetType(Integer))
.Columns.Add("FieldString")