I am struggling with figuring out how to iterate through the src values of a class name. These are gallery images and there are anywhere from 0 to 10 additional images for each product on a page. I am scraping the content so we can add these products to our site as an authorized distributor. The vendor does not provide the data in a format we can easily import.
Set objDescShort = doc.getelementsbyclassname("single__short-description")(0)
Set objDescLong = doc.getelementsbyclassname("ui-tabs-panel ui-corner-bottom ui-widget-content")(0)
Set objImgUrl = doc.getelementsbyclassname("single__gallery-main-img")(0) 'main image
Set objImgUrl2 = doc.getelementsbyclassname("single__gallery-thumbs-img")(0) 'gallery images
ret1 = objDescShort.innerHTML
ret2 = objDescLong.innerHTML
mysheet.Cells(n, 7).Value = ret1
mysheet.Cells(n, 8).Value = ret2
ret3 = objImgUrl.src
mysheet.Cells(n, 9).Value = ret3
galimg = ""
ret4 = doc.getelementsbyclassname("single__gallery-thumbs-img")
For Each srcElm In ret4
galimg = srcElm.src & ", " & galimg
Next
mysheet.Cells(n, 10).Value = galimg
This is just a small section of my code. The url from which I'm extracting this data is http://www.tigertoughgroup.com/products/T62130/
I am having a hard time figuring out what the correct syntax is to get the 'src' values from each 'img' tag in this class.
First, since getElementsByClassName returns a collection of elements, you'll need to use the keyword Set to assign those objects to your variable...
Set ret4 = doc.getelementsbyclassname("single__gallery-thumbs-img")
Then you can use getAttribte to get the src value...
srcElm.getAttribute("src")
Hope this helps!
Related
I'm using UFT (vbscript) to automate a process between SAP and a Web page. Using SAP transaction S_ALR_87013534, I have a piece of code in UFT that will expand the tree completely and extract the value associated with one of the order numbers:
set tree = SAPGuiSession("Session").SAPGuiWindow("Execute Drilldown Report").SAPGuiTree("TableTreeControl")
tree.OpenItemContextMenu "PRJ "&projNum,"PRJ "&projNum
tree.SelectMenuItemById "&EXPAND"
tree.SelectNode "PRJ "&projNum
colKey_plan1 = getColNameFromTitle(tree, "Plan 2--Overall")
rowContainingOrdNum = findBudget(tree, ordNum)
plannedProjectBudget = tree.Object.GetItemText(tree.Object.GetAllNodeKeys(rowContainingOrdNum(0)), colKey_plan1)
Function getColNameFromTitle(tree, title)
set colNames = tree.Object.GetColumnNames
For i = 1 To (colNames.length-1)
selectedColTitle = tree.Object.GetColumnTitleFromName(colNames(i))
If selectedColTitle = title Then
getColNameFromTitle = colNames(i)
Exit For
End If
Next
End Function
Function findBudget(tree, ordNum)
rowContainingOrdNum = Array()
Set columnNames = tree.Object.GetColumnNames()
set columnKeys = tree.Object.GetColumnCol(columnNames(0))
For i = 1 To (columnKeys.length-1)
If InStr(columnKeys(i), ordNum)>0 Then
AddItem rowContainingOrdNum, i
Exit For
End If
Next
findBudget = rowContainingOrdNum
End Function
Function AddItem(arr, val)
ReDim Preserve arr(UBound(arr) + 1)
arr(UBound(arr)) = val
AddItem = arr
End Function
This works perfectly, but when I use a different report, S_ALR_87013543, it's still recognised as a tree but the above code doesn't work as there is no EXPAND option at the Object heading. I'm not very familiar with SAP and all their trees and how to use automation with it, so any guidance or tips are appreciated.
Left is the report I need to expand, and right is the report the code works with:
Solution:
Set TreeObj = SAPGuiSession("Session").SAPGuiWindow("Actual/Plan/Variance").SAPGuiTree("TableTreeControl").Object
Set AllValues = TreeObj.GetAllNodeKeys
Count = AllValues.Count
Found = 0
For i = 0 to Count-1
NodeText = TreeObj.GetNodeTextByKey(AllValues(i))
If NodeText = WBSelement Then
Found = 1
Exit For
End if
Next
If Found = 1 Then
SAPGuiSession("Session").SAPGuiWindow("Actual/Plan/Variance").SAPGuiTree("TableTreeControl").SelectNode WBS
End If
I'm trying to find a way to automate data entry into the raise invoice screen in Sage 50.
All of our order data is held in a different system and we could easily pull together the line items, customer data, etc. automatically but our accounts team currently have to manually select each row, enter the SKU and quantity which is very time consuming.
It appears that the clipboard isn't functional in the Product Code field either - which is really annoying!
Are there any reasonable ways to inject data like this into Sage 50?
as far as i know there is a Excel2Sage Tool or App which can handle mass-importing. i did not used the commercial software last year, but the year before.
i'm actual not know about a free solution for this without developing it.
As alternative you could use AutoIt or something.
best
Eric
Here is an example using VB.Net:
'Declare objects
Dim oSDO As SageDataObject230.SDOEngine
Dim oWS As SageDataObject230.WorkSpace
Dim oSOPRecord As SageDataObject230.SopRecord
Dim oSOPItem_Read As SageDataObject230.SopItem
Dim oSOPItem_Write As SageDataObject230.SopItem
Dim oSOPPost As SageDataObject230.SopPost
Dim oStockRecord As SageDataObject230.StockRecord
'Declare Variables
Dim szDataPath As String
'Create SDO Engine Object
oSDO = New SageDataObject230.SDOEngine
' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\Documents and Settings\All Users\Application Data\Sage\Accounts\2017\")
'Create Workspace
oWS = oSDO.Workspaces.Add("Example")
'Try to connect
If oWS.Connect(szDataPath, "manager", "", "Example") Then
'Create objects
oSOPRecord = oWS.CreateObject("SOPRecord")
oSOPPost = oWS.CreateObject("SOPPost")
oSOPItem_Read = oWS.CreateObject("SOPItem")
oStockRecord = oWS.CreateObject("StockRecord")
'Read an existing Sales Order
oSOPRecord.MoveLast()
'Populate the order header, copying fields from oSOPRecord to oSOPPost
oSOPPost.Header("INVOICE_NUMBER").Value = oSOPRecord.Fields.Item("INVOICE_NUMBER").Value
oSOPPost.Header("ACCOUNT_REF").Value = CStr(oSOPRecord.Fields.Item("ACCOUNT_REF").Value)
oSOPPost.Header("NAME").Value = CStr(oSOPRecord.Fields.Item("NAME").Value)
oSOPPost.Header("ADDRESS_1").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_1").Value)
oSOPPost.Header("ADDRESS_2").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_2").Value)
oSOPPost.Header("ADDRESS_3").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_3").Value)
oSOPPost.Header("ADDRESS_4").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_4").Value)
oSOPPost.Header("ADDRESS_5").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_5").Value)
oSOPPost.Header("DEL_ADDRESS_1").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_1").Value)
oSOPPost.Header("DEL_ADDRESS_2").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_2").Value)
oSOPPost.Header("DEL_ADDRESS_3").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_3").Value)
oSOPPost.Header("DEL_ADDRESS_4").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_4").Value)
oSOPPost.Header("DEL_ADDRESS_5").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_5").Value)
oSOPPost.Header("CUST_TEL_NUMBER").Value = CStr(oSOPRecord.Fields.Item("CUST_TEL_NUMBER").Value)
oSOPPost.Header("CONTACT_NAME").Value = CStr(oSOPRecord.Fields.Item("CONTACT_NAME").Value)
oSOPPost.Header("GLOBAL_TAX_CODE").Value = CShort(oSOPRecord.Fields.Item("GLOBAL_TAX_CODE").Value)
oSOPPost.Header("ORDER_DATE").Value = CDate(oSOPRecord.Fields.Item("ORDER_DATE").Value)
oSOPPost.Header("NOTES_1").Value = CStr(oSOPRecord.Fields.Item("NOTES_1").Value)
oSOPPost.Header("NOTES_2").Value = CStr(oSOPRecord.Fields.Item("NOTES_1").Value)
oSOPPost.Header("NOTES_3").Value = CStr(oSOPRecord.Fields.Item("NOTES_3").Value)
oSOPPost.Header("TAKEN_BY").Value = CStr(oSOPRecord.Fields.Item("TAKEN_BY").Value)
oSOPPost.Header("ORDER_NUMBER").Value = CStr(oSOPRecord.Fields.Item("ORDER_NUMBER").Value)
oSOPPost.Header("CUST_ORDER_NUMBER").Value = CStr(oSOPRecord.Fields.Item("CUST_ORDER_NUMBER").Value)
oSOPPost.Header("PAYMENT_REF").Value = CStr(oSOPRecord.Fields.Item("PAYMENT_REF").Value)
oSOPPost.Header("GLOBAL_NOM_CODE").Value = CStr(oSOPRecord.Fields.Item("GLOBAL_NOM_CODE").Value)
oSOPPost.Header("GLOBAL_DETAILS").Value = CStr(oSOPRecord.Fields.Item("GLOBAL_DETAILS").Value)
oSOPPost.Header("ORDER_TYPE").Value = oSOPRecord.Fields.Item("ORDER_TYPE").Value
oSOPPost.Header("FOREIGN_RATE").Value = CDbl(oSOPRecord.Fields.Item("FOREIGN_RATE").Value)
oSOPPost.Header("CURRENCY").Value = oSOPRecord.Fields.Item("CURRENCY").Value
oSOPPost.Header("CURRENCY_USED").Value = oSOPRecord.Fields.Item("CURRENCY_USED").Value
' Link header to items
oSOPItem_Read = oSOPRecord.Link
'Find the First Record
oSOPItem_Read.MoveFirst()
Do
'Add the existing items to the order
oSOPItem_Write = oSOPPost.Items.Add
'Populate the Fields, copying the data from the existing records
oSOPItem_Write.Fields.Item("STOCK_CODE").Value = CStr(oSOPItem_Read.Fields.Item("STOCK_CODE").Value)
oSOPItem_Write.Fields.Item("DESCRIPTION").Value = CStr(oSOPItem_Read.Fields.Item("DESCRIPTION").Value)
oSOPItem_Write.Fields.Item("NOMINAL_CODE").Value = CStr(oSOPItem_Read.Fields.Item("NOMINAL_CODE").Value)
oSOPItem_Write.Fields.Item("TAX_CODE").Value = CShort(oSOPItem_Read.Fields.Item("TAX_CODE").Value)
oSOPItem_Write.Fields.Item("QTY_ORDER").Value = CDbl(oSOPItem_Read.Fields.Item("QTY_ORDER").Value)
oSOPItem_Write.Fields.Item("UNIT_PRICE").Value = CDbl(oSOPItem_Read.Fields.Item("UNIT_PRICE").Value)
oSOPItem_Write.Fields.Item("NET_AMOUNT").Value = CDbl(oSOPItem_Read.Fields.Item("NET_AMOUNT").Value)
oSOPItem_Write.Fields.Item("TAX_AMOUNT").Value = CDbl(oSOPItem_Read.Fields.Item("TAX_AMOUNT").Value)
oSOPItem_Write.Fields.Item("COMMENT_1").Value = CStr(oSOPItem_Read.Fields.Item("COMMENT_1").Value)
oSOPItem_Write.Fields.Item("COMMENT_2").Value = CStr(oSOPItem_Read.Fields.Item("COMMENT_2").Value)
oSOPItem_Write.Fields.Item("UNIT_OF_SALE").Value = CStr(oSOPItem_Read.Fields.Item("UNIT_OF_SALE").Value)
oSOPItem_Write.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(oSOPItem_Read.Fields.Item("FULL_NET_AMOUNT").Value)
oSOPItem_Write.Fields.Item("TAX_RATE").Value = CDbl(oSOPItem_Read.Fields.Item("TAX_RATE").Value)
'We now need to ensure that the TAX_FLAG is set the same as the item being read otherwise it will be re calculated
oSOPItem_Write.Fields.Item("TAX_FLAG").Value = CInt(oSOPItem_Read.Fields.Item("TAX_FLAG").Value)
'Loop until there are no more existing items
Loop Until oSOPItem_Read.MoveNext = False
'destroy the oSOPItem_Write object
oSOPItem_Write = Nothing
'write a new item
oStockRecord.MoveLast()
oSOPItem_Write = oSOPPost.Items.Add
' Populate other fields required for Invoice Item
' From 2015 the update method now wraps internal business logic
' that calculates the vat amount if a net amount is given.
' If you wish to calculate your own Tax values you will need
' to ensure that you set the TAX_FLAG to 1 and set the TAX_AMOUNT value on the item line
' ***Note if a NVD is set the item line values will be recalculated
' regardless of the Tax_Flag being set to 1***
oSOPItem_Write.Fields.Item("STOCK_CODE").Value = oStockRecord.Fields.Item("STOCK_CODE").Value
oSOPItem_Write.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
oSOPItem_Write.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
oSOPItem_Write.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)
oSOPItem_Write.Fields.Item("QTY_ORDER").Value = CDbl(2)
oSOPItem_Write.Fields.Item("UNIT_PRICE").Value = CDbl(50)
oSOPItem_Write.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSOPItem_Write.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
oSOPItem_Write.Fields.Item("COMMENT_1").Value = CStr("")
oSOPItem_Write.Fields.Item("COMMENT_2").Value = CStr("")
oSOPItem_Write.Fields.Item("UNIT_OF_SALE").Value = CStr("")
oSOPItem_Write.Fields.Item("TAX_RATE").Value = CDbl(20)
'Destroy the oSOPItem_Write object
oSOPItem_Write = Nothing
'Post the order
If oSOPPost.Update() Then
MsgBox("Order Updated Successfully")
Else
MsgBox("Order Update Failed")
End If
'Disconnect and destroy the objects
oWS.Disconnect()
oSDO = Nothing
oWS = Nothing
oSOPRecord = Nothing
oSOPItem_Read = Nothing
oSOPItem_Write = Nothing
oSOPPost = Nothing
oStockRecord = Nothing
End If
Exit Sub
All of the current commercial products will require you to put your data into a specific format (column order and file type) anyway, so if you can do that, then bring everything into Excel, and then adapt the code listed above for VB.Net into VBA. It's fairly straightforward, mainly passing data to an array and then looping through.
If you want specific assistance, show us the structure of your Order data, and then we can do something
Cheers
Paul
I have the below table in word that I'm trying to write a script to replace the contents of the below cell with a different customer payment (i.e replace the £1,100 with £2,000). Below is a snippet of my script but the when I write back to the cell it loses all the formatting and the numbered list.
How can I keep replace the cell data with very similar data and still keep the formatting?
ps. I've simplified the contents of the cell to make it easier to read, so the code won't apply to exactly that content
DescPlan = Trim(t1.Cell(2, 2).Range.Text)
DescTest = InStr(1, DescPlan, ":")
finalString = Left(DescPlan, DescTest)
t1.Cell(2, 2).Range.Text = Replace(DescPlan, finalString, "Payment by the customer of " + Format(v, "Currency") + " will be due upon completion of items below:")
Not sure if this helps but you are using a table so what works for excel should also work for you.
Sub replace_keep_format()
Dim t1 As Range
Dim sStrng As String, rStrng As String
Dim i As Integer
sStrng = "£1,100"
rStrng = "£2,000"
i = 1
Do Until ThisWorkbook.Sheets(1).Range("a" & i) = ""
Set t1 = ThisWorkbook.Sheets(1).Range("a" & i)
t1 = Replace(Expression:=t1, Find:=sStrng, Replace:=rStrng)
i = i + 1
Loop
End Sub
I have a rather interesting problem going on in my excel problem. Basically I have two Workbooks, lets say
ACTIVE.xlsm and EXTERNAL.xls
Active has a macro that opens external and drops in some data from active, then reads a solution on external and returns it to the user on the active workbook. Whew. Thats a tough one. Now that we're through that, heres the problem. It is my personal opinion that there is a glitch in external (which I'm unable to fix as its a company read-only file) that when active drops in its data into a specific drop-down (data validation) cell (other data validation cells work fine with this macro, its only this one that doesn't), the solution cell on external doesnt update, but rather jumps to "#N/A". At this point, my VBA has run into a bug, and the code stops with external still open. When I look at external, I've deduced that this singular variable cell is the problem amdist all the other variable cells determining the solution.
The variable cell at this point contains the number "150" and although the data validation allows for this option, the solution cell still says "#N/A". It isn't until I physically click inside of the cell with "150" like I'm going to edit it, then I press enter, that the #N/A corrects to the appropriate solution (Let's say this solution is "$352.08") Keep in mind, the value within the variable cell never changed, it perhaps only was "refreshed".
Any ideas as to why this is happening? I know this is long-winded, but I suppose that's why I have been unable to find a solution thus far. Perhaps there's a VBA workaround that can simulate clicking in the cell, then pressing enter, who knows!
Thanks in advance!
Here's some code for funsies, though I don't believe this is a code issue, as it works for all other "external"'s that I've been working with.
...ElseIf Left(Range("C9").Value, 4) = "LA23" Then
CurWkbk = ActiveWorkbook.Name
PartNo = Worksheets("LINAK ONE").Range("C6").Value
PartNoID_B = Worksheets("GPL Pull").Range("B8").Value
PartNoID_C = Worksheets("GPL Pull").Range("C8").Value
PartNoID_D = Worksheets("GPL Pull").Range("D8").Value
PartNoID_E = Worksheets("GPL Pull").Range("E8").Value
PartNoID_F = Worksheets("GPL Pull").Range("F8").Value
PartNoID_G = Worksheets("GPL Pull").Range("G8").Value
PartNoID_H = Worksheets("GPL Pull").Range("H8").Value
PartNoID_I = Worksheets("GPL Pull").Range("I8").Value
PartNoID_J = Worksheets("GPL Pull").Range("J8").Value
PartNoID_K = Worksheets("GPL Pull").Range("K8").Value
Workbooks.Open ("EXTERNAL.xls")
Workbooks("EXTERNAL.xls").Sheets("Price").Activate
Range("E9").Value = PartNoID_B
Range("G9").Value = PartNoID_C
Range("I9").Value = PartNoID_D
Range("K9").Value = PartNoID_E
Range("M9").Value = PartNoID_F
Range("O9").Value = PartNoID_G
Range("Q9").Value = PartNoID_H
Range("S9").Value = PartNoID_I
Range("S9").Select
ActiveCell.Calculate
Range("U9").Value = PartNoID_J
Range("W9").Value = PartNoID_K
Range("AD7").Value = "LUS"
LUSPrice = Range("AE9").Value
Range("AD7").Value = "USD"
USDPrice = Range("AE9").Value
Range("AD7").Value = "DKK"
DKKPrice = Range("AE9").Value
Windows(CurWkbk).Activate
ActiveWorkbook.Sheets("Discount Calculator").Activate
Range("D5").Value = LUSPrice
ActiveWorkbook.Sheets("PRICE GENERATOR").Activate
Range("C25").Value = PartNo & " Pricing | LUS: $" & Round(LUSPrice, 2) & " | USD: $" & Round(USDPrice, 2) & " | DKK: kr " & Round(DKKPrice, 2)
MsgBox "Tillykke! Pricing for the " & PartNo & " has been generated. The price has been entered into the discount calculator.", , "Pricing Generated"
Workbooks("EXTERNAL.xls").Close False...
you should be using fully qualified references to cells
this is a rewrite of your code
...ElseIf Left(Range("C9").Value, 4) = "LA23" Then ' which workbook/sheet ????
CurWkbk = ActiveWorkbook.Name ' which workbook ????
PartNo = Worksheets("LINAK ONE").Range("C6").Value ' which workbook ????
With Worksheets("GPL Pull")
PartNoID_B = .Range("B8").Value
PartNoID_C = .Range("C8").Value
PartNoID_D = .Range("D8").Value
PartNoID_E = .Range("E8").Value
PartNoID_F = .Range("F8").Value
PartNoID_G = .Range("G8").Value
PartNoID_H = .Range("H8").Value
PartNoID_I = .Range("I8").Value
PartNoID_J = .Range("J8").Value
PartNoID_K = .Range("K8").Value
End With
Workbooks.Open ("EXTERNAL.xls")
With Workbooks("EXTERNAL.xls").Worksheets("Price")
.Range("E9").Value = PartNoID_B
.Range("G9").Value = PartNoID_C
.Range("I9").Value = PartNoID_D
.Range("K9").Value = PartNoID_E
.Range("M9").Value = PartNoID_F
.Range("O9").Value = PartNoID_G
.Range("Q9").Value = PartNoID_H
.Range("S9").Value = PartNoID_I
.Range("S9").Calculate
.Range("U9").Value = PartNoID_J
.Range("W9").Value = PartNoID_K
.Range("AD7").Value = "LUS"
LUSPrice = .Range("AE9").Value
.Range("AD7").Value = "USD"
USDPrice = .Range("AE9").Value
.Range("AD7").Value = "DKK"
DKKPrice = .Range("AE9").Value
End With
CurWkbk.Worksheets("Discount Calculator").Range("D5").Value = LUSPrice ' which workbook ????
CurWkbk.Worksheets("PRICE GENERATOR").Range("C25").Value = PartNo & " Pricing | LUS: $" & Round(LUSPrice, 2) & " | USD: $" & Round(USDPrice, 2) & " | DKK: kr " & Round(DKKPrice, 2)
MsgBox "Tillykke! Pricing for the " & PartNo & " has been generated. The price has been entered into the discount calculator.", , "Pricing Generated"
Workbooks("EXTERNAL.xls").Close False...
I need to retrieve only the values from nodes which their attribute are "true". Here's what I have and what I need - appreciate any help:
<AudioTracks>
<original available="true">ENG</original>
<localized available="false">SPA</localized>
<localized available="true">POR</localized>
</AudioTracks>
Here's my code, it will retrieve all values, but I would like to find a way to only retrieve ENG and POR (true). I can't seem to find a suitable way to do it.
'AudioTracks
Set oAudioNodes = featureNode.SelectSingleNode("videos/video/AudioTracks")
For i = 0 To oAudioNodes.ChildNodes.Length
sAudio = oAudioNodes.ChildNodes.Item(i).nodeTypedValue & ";" & sAudio
Next
sAudio = Left(sAudio, Len(sAudio) - 1)
ActiveSheet.Cells(intRow, colAudioTracks).Value = NullCheck(sAudio)
sAudio = ""
sRawData = ""
This will return me ENG;SPA;POR ... But I need it to return only ENG;POR
Help me Obi Wan, you're my only hope.
Eureka. I have found a way to make this happen. Not beautiful but works just fine! I just did a small conditional using the getAttribute property. As a parameter, I have just used the attribute name (in this case "available"). Ha! Beautiful - for me.
Set oAudioNodes = featureNode.SelectSingleNode("videos/video/AudioTracks")
txt = ""
For i = 0 To oAudioNodes.ChildNodes.Length
txt = oAudioNodes.ChildNodes.Item(i).getAttribute("available")
If txt = "true" Then sAudio = oAudioNodes.ChildNodes.Item(i).nodeTypedValue & ";" & sAudio
Next
sAudio = Left(sAudio, Len(sAudio) - 1)
ActiveSheet.Cells(intRow, colAudioTracks).Value = NullCheck(sAudio)
sAudio = ""
sRawData = ""
txt = ""