How to copy HTML span attribute to excel by vba - html

I am trying to copy web span value to excel sheet by excel vba. I try copy from input box which same value with span but it's unable to copy / null value. This HTML to copy
<td nowrap class="iddisplay"><span style="font-size: 14px" tabIndex="0">IAR/19326/8JM3Z</span>
<input type="hidden" name="transactionId" id="transactionId" value="IAR193268JM3Z"></td>
so i want to copy value IAR/19326/8JM3Z from span or IAR193268JM3Z from transactionId value
The excel vba code that i use
Set str_val12 = IE.document.getElementById("transactionId")
clip.SetText str_val12.innerText
'clip.SetText str_val12.value
clip.PutInClipboard
test.Cells(i + 2, 6).Select
test.Cells(i + 2, 6).PasteSpecial "Unicode Text"
Thanks

If the css class iddisplay is only used in that specific td tag:
Cells(i + 2, 6) = IE.document.getElementsByClassName("iddisplay")(0).FirstChild.innertext

I haven't tested this but something along the lines of:
Dim element as Variant
For Each element in IE.document.getElementsById("transactionId")
If element.value = "IAR193268JM3Z" Then
Set str_val12 = element.innerText
test.cells(i + 2, 6).Value = str_val12
End If
Next element
Let me know if this throws an error and on which line. I am unsure if .Value is a way to check the value="IAR193268JM3Z" embedded within the input tag, but let's see.

Related

VBA: Access element inside a div loaded with angularjs, when ID and Classname changes randomly

I am a beginner in VBA and I make an application that fills the data coming from a xls page to a website that uses angularjs.
the website contains a table to fill out, so its ID and classname changes the four latest number randomly with each refresh. (for exemple: the code source below: 02XC of ID will be change to something different, but the prefix will remain the same). how can i manipulate this table?
Code source web site
<div tabindex="-1" class="ui-grid-cell ng-scope ui-grid-coluiGrid-02XC cell editable" id="1554799061475-1-uiGrid-02XC-cell" role="gridcell" aria-selected="false" ng-class="{ 'ui-grid-row-header-cell': col.isRowHeader }" ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.uid" ui-grid-cell="" ui-grid-one-bind-id-grid="rowRenderIndex + '-' + col.uid + '-cell'">[Here is the web table that i want to upload values][1]</div>
my code
Set objHtml = New HTMLDocument
Set objHtml = internetExplorer.document
Set modric = objHtml.getElementsByClassName("ui-grid-cell ng-scope ui-grid-coluiGrid-02XC cell editable")
If modric.Length <> 0 Then
For q = 0 To modric.Length - 1
modric(q).Click
modric(q).innerText = Workbooks("remplir").Worksheets("sheet1").Range("F1").Offset(n + 1, 0).Value
Next q
End If
as i said, in the next refresh, 02XC 'll be change to a four other random number.
I want to get the ID or classname for each refresh to manipulate the table.
or every others ways that could help me to manage the table.
sorry my English is so poor. hope your understand me :)
You can use attribute = value selector with starts with (^) operator
[id^='1554799061475-1-uiGrid-']
I am not sure if you want a single or multiple matches
single match
Dim ele As Object
Set ele = objHtml.querySelector("[id^='1554799061475-1-uiGrid-']")
This assumes the id starts with 1554799061475-1-uiGrid- and only the end bit changes.
You can use querySelectorAll to return a nodeList if more than one match possible.

Convert Hyperlinks to HTML code in Excel

I have a column of hyperlinks in an Excel file and I want to convert them to their respective HTML code:
Link Name
I found ways to extract the link only (as text), but I need the whole HTML code as text to replace the hyperlink in the cell.
I've searched and searched but no one needed this answer, I guess. Can someone help?
It is actually a fairly straightforward method to yank the .Address and optional .SubAddress from the Hyperlinks collection object. The .TextToDisplay property is simply the value or text of the cell.
Sub html_anchors()
Dim a As Range, u As String, l As String
Dim sANCHOR As String: sANCHOR = "%L%"
For Each a In Selection
With a
If CBool(.Hyperlinks.Count) Then
l = .Text
u = .Hyperlinks(1).Address
If Right(u, 1) = Chr(47) Then u = Left(u, Len(u) - 1)
.Hyperlinks(1).Delete
.Value = Replace(Replace(sANCHOR, "%U%", u), "%L%", l)
End If
End With
Next a
End Sub
Select all of the cells you want to process and run the routine. If any cell in your selection does not contain a hyperlink, it will be ignored.

How to create img tags dynamically from the code behind

I have the following img tag:
<img id="cross" runat="server" />
I would like to create several img tags according to data the I'm getting back from the Database. but I'm keep getting an error 'System.Web.UI.HtmlControls.HtmlImage' does not allow child controls.
How can I create img tag dynamically?
For example if I'm getting back from the database 5 dots(XCoord,YCoord) to be created I want to create new 5 images.
Here is my code:
Dim ds As DataSet = dba.GetIncidentsByZone(135, "02/11/2015", "05/12/2015", m_User.CompanyCode)
If Not ds Is Nothing Then
For Each dr As DataRow In ds.Tables(0).Rows()
cross.Controls.Add(New HtmlImage() With {.Src = "C:/Inetpub/temp/pointer.gif", .Alt = ""})
cross.Style.Add("left", dr("XCoord").ToString() + "px")
cross.Style.Add("top", dr("YCoord").ToString() + "px")
cross.Attributes.Add("style", "visibility:visible")
Next
End If
Based on your comment, your loop needs to look more like this:
If Not ds Is Nothing Then
For Each dr As DataRow In ds.Tables(0).Rows()
Dim newImage as New HtmlImage() With {.Src = "C:/Inetpub/temp/pointer.gif", .Alt = ""}
newImage.Style.Add("left", dr("XCoord").ToString() + "px")
newImage.Style.Add("top", dr("YCoord").ToString() + "px")
someOtherContainerItemLikeADiv.Controls.Add(newImage)
Next
End If
On each iteration of the loop you need to make a new image, set it's properties and then add that to some kind of control that allows child controls, like a div.

Referencing unchecked checkboxes with vbscript causes an error

I am running into a problem with my vbscript code. My HTML code looks like this
<input type='checkbox' name='DisplayRow' id='DisplayRow1' />
<input type='checkbox' name='DisplayRow' id='DisplayRow2' />
<input type='checkbox' name='DisplayRow' id='DisplayRow3' />
This is done because above there is another checkbox that calls a javascript function that will check or uncheck all of the "DisplayRow" checkboxes. The javascript function uses getElementsByName to return all of the checkboxes named "DisplayRow".
When the form's submit button is clicked the action sends it to an ASP page (classic ASP) that grabs all of the objects on the calling form by using the Request.Form command. The Request.Form command looks at the "name" attribute, not the "id" attribute of the object.
This seems to be working fine for all of the other form objects. When it gets to the checkboxes because the "name" attribute uses the same name for all of the check boxes it returns an array. The individual checkboxes can be accessed like this:
Request.Form("DisplayRow")(x)
Where x references the individual checkbox in the array.
If the checkboxes are checked I can loop through the array without any problems. If 1 or more or all of the checkboxes are unchecked then when the code references the first checkbox in the array that is unchecked the page crashes. Nothing is executed after the Request.Form command fails.
I have tried enclosing the Request.Form("DisplayRow")(x) in an IsNull function in an If statement but it still takes the program down.
Has anyone else ran into this and found a work around?
Edit
For some reason stackoverflow is not letting me add more than one comment.
#Cory. Thanks for the information
#jwatts1980. Count works but it does not let me know which of the checkboxes are checked. If the count is greater than 0 I can loop through them but if the first one is unchecked I am right back where I started with a crashed page.
You cannot do it this way because unchecked checkboxes will not be submitted in the post, only the checked ones.
I would approach this differently:
First I would add a value attribute to the checkboxes, as so:
<input type='checkbox' name='DisplayRow' id='DisplayRow1' value="1" />
<input type='checkbox' name='DisplayRow' id='DisplayRow2' value="2" />
<input type='checkbox' name='DisplayRow' id='DisplayRow3' value="3" />
Notice the value is the same as the index, this will be needed in the code.
Next I would use .Split() to gather the checkboxes selected in an array, since the values will come in as a string separated by comma, ie: 1,2,3 to your .Form() value.
Rows = Request.Form("DisplayRow")
'check if any are selected first
If Rows <> "" Then
'make an array with each value selected
aRows = Split(Rows,",")
'loop through your array and do what you want
For i = lBound(aRows) to uBound(aRows)
Response.Write "DisplayRow" & aRows(i) & " was Selected."
Next
End If
This way you only process the results for the one's selected, and ignore the others.
I've always found this essential for my library...
'GetPostData
' Obtains the specified data item from the previous form get or post.
'Usage:
' thisData = GetPostData("itemName", "Alternative Value")
'Parameters:
' dataItem (string) - The data item name that is required.
' nullValue (variant) - What should be returned if there is no value.
'Description:
' This function will obtain the form data irrespective of type (i.e. whether it's a post or a get).
'Revision info:
' v0.1.2 - Inherent bug caused empty values not to be recognised.
' v0.1.1 - Converted the dataItem to a string just in case.
function GetPostData(dataItem, nullVal)
dim rV
'Check the form object to see if it contains any data...
if request.Form = "" then
if request.QueryString = "" then
rV = nullVal
else
if request.QueryString(CStr(dataItem))="" then
rV = CStr(nullVal)
else
rV = request.QueryString(CStr(dataItem))
end if
end if
else
if request.Form(CStr(dataItem)) = "" then
rV = CStr(nullVal)
else
rV = request.Form(CStr(dataItem))
end if
end if
'Return the value...
GetPostData = rV
end function
To use the function you simply pass in the form or query string item you're looking for and what to replace empty values with...
Dim x
x = GetPostData("chkFirstOne", false)
You can keep using your existing code by adding a single condition:
If Request.Form("DisplayRow").Count > 0 Then
'your code here
Else
'consider adding message saying nothing was selected
End If

Accessing Inner Text Anchor Tag with Selenium

I am trying to iterate a table and access the values via XPath,
for example:
/html/body/div[2]/form/div/table/tbody/tr/td[2]/table[4]/tbody/tr[3]/td[10]/span/a
/html/body/div[2]/form/div/table/tbody/tr/td[2]/table[4]/tbody/tr[4]/td[10]/span/a
/html/body/div[2]/form/div/table/tbody/tr/td[2]/table[4]/tbody/tr[5]/td[10]/span/a
/html/body/div[2]/form/div/table/tbody/tr/td[2]/table[4]/tbody/tr[...]/td[10]/span/a
the values contained in the inner html of an anchor tag:
<td>
<span id="TUFLMTU1MA%3D%3D">
<a onclick="return false" target="_top" href="">VALUE I WANT</a>
</span>
</td>
I've tried the Xpath statement which normally works except when using a hyperlink. I can't do it with the id attribute because they are all dynamic. The text I am trying to grab is "VALUE I WANT" above. Also, "VALUE I WANT" changes throughout the table, so I can't just go based on that because it is not that same value everytime.
I am using Selenium RC not the web driver.
Put your xpath in 'for' loop and iterate it as many times as you have elements
for(int x = 1; x < your_neumber_of_elements; x++) {
WebElement e = driver.findElement(By.xpath("//table/tbody/tr/td[2]/table[4]/tbody/tr[" + x + "]/td[10]/span/a"));
Syste.out.println(e.getText());
}