I have the following:
For Each dist In dtDataTableDist.Rows
For Each det In dtDataTableDet.Rows
If Not (det("LoginName") Is dist("LoginName")) Then Continue For
Next
Next
Within the inner For Each I have
Not (det("LoginName") Is dist("LoginName")) Then Continue For
What I am trying to do here is to say that if the login in the inner for each is not the same
as the LoginName in the out then skip the rest of the code in the inner loop and continue to the next inner for each.
Although the det("LoginName") and dist("LoginName") both have the same value of "899"
I would think that it would not skip the rest of the code in the inner loop but it does.
Is is used for comparing objects... in other words are the two object references the exact same object.
You should be using normal comparison...
If Not (det("LoginName") = dist("LoginName")) Then Continue For
Or...
If det("LoginName") <> dist("LoginName") Then Continue For
Related
Anybody have any tips for looping, and continue? For example, I placed about 2500 pnrs on a queue, and I need to add a remark to each of them. Is it possible for a script to add the remark then move to the next pnr?
For example, I placed about 2500 pnrs on a queue, and I need to add a remark to each of them. Is it possible for a script to add the remark then move to the next pnr?
Loops are supported in Scribe but have to be built manually by creating your own iteration variables and breaking the loop manually when you know the work is complete.
What you are describing is definitely possible, but working in queues can be difficult as there are many possible responses when you try to end the PNRs. You'll have to capture the response to detect whether you need to do something else to get out of the error condition (e.g. if a PNR warning indicates you have to double-end the record).
If possible, its likely simpler to work off the queue by collecting all PNR locators and then looping through that list, adding your remarks, and then ending the PNRs. You'll still have to capture the response to determine if the PNR is actually ended properly, but you won't have to deal with the buggy queue behavior. A basic Scribe loop sample is below. Note that I haven't been a Scribe developer for a while and I did this in Notepad so there might be some errors in here, but hopefully it's a good starting point.
DEFINE [ROW=N:8] ;iteration variable/counter
DEFINE [LOCATOR_FILE=*:60] ;File Path
DEFINE [TEMP_LOCATOR=*:6] ;pnr locator variable, read from the temp file
DEFINE [BREAK=*:1] ;loop breaking variable
OPEN F=[TEMP_LOCATOR] L=0 ;open the file of locators
[BREAK] = ""
[ROW] = 0
REPEAT
[ROW] = [ROW] + 1
[TEMP_LOCATOR] = "" ;Reset temp locator variable, this will break our loop
READ F=[LOCATOR_FILE] R=[ROW] C=1 [TEMP_LOCATOR]
IF $[TEMP_LOCATOR] = 6 THEN ;test length of locator, if this is 6 chars, you have a good one, pull it up and add your remark
»"5YOUR REMARK HERE"{ENTER}«
»ER{ENTER}«
;trap errors
READ F="EMUFIND:" R=0 C=0 [TEMP_LOCATOR] ;read for the locator being present on this screen, which should indicate that the ER was successful - you'll have to trap other errors here though
IF [#SYSTEM_ERROR] = 0 THEN ;this locator was found, ER appears successful
»I{ENTER}« ;Ignore this PNR and move to the next one
ELSE
[BREAK] = "Y" ;error found afeter ER, break loop. Maybe show a popup box or something, up to you
ENDIF
ELSE ;No locator found in file, break the loop
[BREAK] = "Y"
ENDIF
UNTIL [BREAK] = "Y"
CLOSE [LOCATOR_FILE]
Is there a way to get the next or previous tag in AwesomeWM Lua Config?
Reason :- I want to get the next or previous tag to set the focused clients tag to it and then move to the tag.
I know there is awful.tag.viewnext which moves to the next tag but unsure about how to get the tag it will move to to set this on a client.
Thanks in advance
Well... yes, there is a way, but there is not a completely trivial one.
First, let's look at the default config. What existing functionality has to get next/previous tags? That is the mouse wheel on the taglist:
https://github.com/awesomeWM/awesome/blob/7a759432d3100ff6870e0b2b427e3352bf17c7cc/awesomerc.lua#L160-L161
So, how does awful.tag.viewnext and viewprev get the next tag? These functions just call viewidx with an idx of 1 or -1, e.g.:
https://github.com/awesomeWM/awesome/blob/7a759432d3100ff6870e0b2b427e3352bf17c7cc/lib/awful/tag.lua#L1494
So, awful.tag.viewidx can do what we want. How does it do it?
It gets a table of all un-hidden tags, finds the index of the currently selected tag and then uses gears.math.cycle to compute the index of the tag with the requested offset.
https://github.com/awesomeWM/awesome/blob/7a759432d3100ff6870e0b2b427e3352bf17c7cc/lib/awful/tag.lua#L1452-L1469
For you, something like the following should do the trick:
function get_tag_at_offset(i, s)
s = screen[s or awful.screen.focused()]
local tags = s.tags
local showntags = {}
for _, t in pairs(tags) do
if not awful.tag.getproperty(t, "hide") then
table.insert(showntags, t)
end
end
for k, t in ipairs(showntags) do
if t == sel then
return showntags[gears.math.cycle(#showntags, k + i)]
end
end
end
The above function can be used like get_tag_at_offset(1) to get the next tag and with argument -1 for the previous. Where possible, I would recommend to also pass in a screen via the second argument.
Also, all of this is completely untested and just written on the spot. There could very well be typos and other mistakes in here.
I have a webpage with a combobox to sort a list by Price, Name,... The list is in many pages, so I need to get all elements first and after, I will sort by and check if the elements are correct. Right?
I am trying to do it and navigate for all pages and get all elements. But it is only taking the elements in first page. I am totally new in Robot framework.
Does anyone have a suggestion how I can do it?
${name_list_actual} Create List
${cnt_pages}= Get Element Count //div[#class='container index-new-p']/div/nav[#class='text-center']/ul/li/*
Log To Console ${cnt_pages}
:FOR ${n} IN RANGE 1 ${cnt_pages}
\ Click link //div[#class='container index-new-p']/div/nav/ul/li[${n}]/a
\ ${cnt}= Get Element Count //*[#class="title"]/*
:FOR ${i} IN RANGE 1 ${cnt}
\ ${get_names} Get Element Attribute //table[#class='result-table']/tbody/tr[${i}]/td/div/div[2]/div/a text
\ Append To List ${name_list_actual} ${get_names}
${get_names}= Select All From List //table[#class='result-table']/tbody/tr[${i}]/td/div/div[2]/div/a
\ Log To Console ${name_list_actual}
\ Continue For Loop
Thanks so much
First and foremost, by your code sample's indent it looks like you're doing nested for loops - an outer one for the changing the pages, and an inner that'll get the text in each row. The thing is - Robot Framework doesn't support nested for loops - see the documentation.
What happened on execution is the first loop (the pagination) ran with just two statements and finished:
\ Click link //div[#class='container index-new-p']/div/nav/ul/li[${n}]/a
\ ${cnt}= Get Element Count //*[#class="title"]/*
Then all the rest were executed as part of the second.
A solution would be to have a keyword "Get All Values In The Table" that'll hold the inner loop, and call it in the current outer, which will paginate.
Another issue - you're using IN RANGE, passing 1 as start and ${cnt} as end; if it had value of 4, you probably expect the tracking variable to get all values from 1 to 4.
Yet range works with the first argument inclusive, and up to - but not getting to - the second argument; thus it covers the range 1 to 3. To salvage that, you'd need to set the upper bound to cnt+1, e.g. ${cnt + 1}.
Minor stuff:
You have a statement that's within the loop block, but not prefixed with \:
${get_names}= Select All From List //table[#class='result-table']/tbody/tr[${i}]/td/div/div[2]/div/a
I'm surprised it didn't give you a syntax error - it effectively breaks the loop, and the framework should complain the next lines are prefixed as if in a loop, but one is not started.
-
When you are changing the pages by the click, you are not making sure the UI has loaded the data for the new page. If this happens through ajax calls, you may very well be working with the previous page's data, thinking it is the new one - the selenium click returns control very fast, and the operands for getting the text are running - while the UI still waits for the new data and is displaying the previous one.
-
In RF version 3.1 the loop syntax is different - the block members are not prefixed with \, and it's closed with an END statement.
I'd suggest to migrate to it - a) the current one is going to be eventually deprecated, and b) in the new one the nesting would have been marked as syntax error (you're starting a new loop without END-ing the running one), instead of silently passing with unexpected behavior.
Hello I am getting a general run time error. This am working with preloaded drop downs and I have another one function before this that works just fine. but when it tries to run this I get the error.
I have tried with different properties like innertext, html id, ect.. but this get the same error.
Sub WebList(DropDown)
Set myPage=Browser("title:=.*").Page("title:=.*")
Set myWebList=Description.Create()
myWebList("micClass").value="WebList"
Set AllWebList=myPage.ChildObjects(myWebList)
totalWebList=AllWebList.count()
For i = 0 To totalWebList
If AllWebList(i).GetRoProperty("name") = DropDown Then
AllWebList(i).select ("GO")
wait(3)
Exit for
End If
Next
Set myPage = nothing
Set myWebList2 = Nothing
Set AllWebList2 = nothing
End Sub
I want the dropdown to be selected. Thanks for any help/suggestion. Also if I can improve on any lines to make it for dynamic and experienced coder, please do suggest them.
You have an error in your For loop, if there are no lists with the specified name you will access one more than actually exist. This is due to the fact that To in vbscript is inclusive and the index starts at 0. If the list is found the code works for me.
The For loop should be:
For i = 0 to totatlWebList - 1
(first question here, sorry if I am breaking a piece of etiquette)
My site is running on an eCommerce back end provider that I subscribe to. They have everything in classic ASP. They have a black box function called import_products that I use to import a given text file into my site's database.
The problem is that if I call the function more than once, something breaks. Here is my example code:
for blah = 1 to 20
thisfilename = "fullcatalog_" & blah & ".csv"
Response.Write thisfilename & "<br>"
Response.Flush
Call Import_Products(3,thisfilename,1)
Next
Response.End
The first execution of the Import_Products function works fine. The second time I get:
Microsoft VBScript runtime error '800a0009'
Subscript out of range: 'i'
The filenames all exist. That part is fine. There are no bugs in my calling code. I have tried checking the value of "i" before each execution. The first time the value is blank, and before the second execution the value is "2". So I tried setting it to null during each loop iteration, but that didn't change the results at all.
I assume that the function is setting a variable or opening a connection during its execution, but not cleaning it up, and then not expecting it to already be set the second time. Is there any way to find out what this would be? Or somehow reset the condition back to nothing so that the function will be 'fresh'?
The function is in an unreadable include file so I can't see the code. Obviously a better solution would be to go with the company support, and I have a ticket it in with them, but it is like pulling teeth to get them to even acknowledge that there is a problem. Let alone solve it.
Thanks!
EDIT: Here is a further simplified example of calling the function. The first call works. The second call fails with the same error as above.
thisfilename = "fullcatalog_testfile.csv"
Call Import_Products(3,thisfilename,1)
Call Import_Products(3,thisfilename,1)
Response.End
The likely cause of the error are the two numeric parameters for the Import_Products subroutine.
Import_Products(???, FileName, ???)
The values are 3 and 1 in your example but you never explain what they do or what they are documented to do.
EDIT Since correcting the vender subroutine is impossible, but it always works for the first time it's called lets use an HTTP REDIRECT instead of a FOR LOOP so that it technically only gets called once per page execution.
www.mysite.tld/import.asp?current=1&end=20
curr = CInt(Request.QueryString("current"))
end = CInt(Request.QueryString("end"))
If curr <= end Then
thisfilename = "fullcatalog_" & curr & ".csv"
Call Import_Products(3,thisfilename,1)
Response.Redirect("www.mysite.tld/import.asp?current=" & (curr + 1) & "&end=" & end)
End If
note the above was written inside my browser and is untested so syntax errors may exist.