QTP narrow a list of ChildObjects - vbscript

[The description is a bit fudged to obfuscate my real work for confidentiality reasons]
I'm working on a QTP test for a web page where there are multiple HTML tables of items. Items that are available have a clickable item#, while those that aren't active have an item# as plain text.
So if I have a set of ChildObjects like this:
//This is the set of table rows that contain item numbers, active or not.
objItemRows = Browser("browserX").Page("pageY").ChildObjects("class:=ItemRow")
What is the simplest way in QTP land to select only the clickable link-ized item #s?
UPDATE: The point here isn't to select the rows themselves, it's to select only the rows that have items in them (as opposed to header/footer rows in each table). If I understand this correctly, I could then use objItemRows.Count to count how many items (available and unavailable) there are. Could I then use something like
desItemLink = Description.Create
desItemLink("micclass").value = "Link"
objItemLinks = objItemRows.ChildObjects(desItemLink)
To get the links within only the item rows?
Hope that clarifies things, and thanks for the help.

I think I have this figured out.
Set desItemLink = description.create
desItemLink("micclass").value = "Link"
desItemLink("text").RegularExpression = True
//True, Regex isn't really required in this example, but I just wanted to show it could be used this way
//This next part depends on the format of the item numbers, in my case, it's [0-9]0000[0-9]00[0-9]
For x = 0 to 9
For y = 0 to 9
For z = 0 to 9
strItemLink = x & "0000" & y & "00" & z
desItemLink("text").value = strItemLink
Set objItemLink = Browser("browser").Page("page").Link(desItemLink)
If objItemLink.Exist(0) Then
//Do stuff
End If
Next
Next
Next
Thanks for your help anyways, but the code above will iterate through links with names in a given incrementing format.

Related

Speeding up adding validation lists to a spread range of cells using vba

I am working with a fairly small worksheet that has been developed by someone else. In this worksheet I have approx. 500 rows and some 100 columns (these values change dynamically).
The document adds validation lists to some cells based on a named range in another worksheet in the same workbook. This currently works, but very slowly.
The cells I would like to target are cells that on the same row, in column A, have a certain value. The cells should also have a specific name in its "header".
Currently, I am using a find statement to find all correct columns, and then for each of those columns I check the value in column A for the correct one, and if it is, I add the range.
Now to the question; How can I speed this up? When the sheet is at its largest it takes over a minute to complete the code, and since that happens when you open the sheet, people using the sheet are complaining. :)
Application.ScreenUpdating = False
Application.EnableEvents = False
Sheets(A).Activate
Sheets(A).Unprotect Password:=Str_SheetPassword
'Get each data ranges
Set Rg_TitleRange = ...
Set Rg_dataRange = ...
'Loop on each column that contains the keyword name
Set Rg_ActionFound = Rg_TitleRange.Find(Str_ColName, LookIn:=xlFormulas, _
lookAt:=xlWhole, SearchOrder:=xlByRows, MatchCase:=True)
If Not Rg_ActionFound Is Nothing Then
'Loop on each action column
Do
'For each data row, update the cells with validation list
For Int_RowIndex = 0 To Rg_dataRange.Rows.Count - 1
'Change cells wich are at the intersection of test definition row and action name column.
If Rg_dataRange(Int_RowIndex, 1) = Str_RowName Then
Set Val_ActionValidationList = Rg_dataRange(Int_RowIndex, Rg_ActionFound.Column).Validation
Val_ActionValidationList.Delete
Rg_dataRange(Int_RowIndex, Rg_ActionFound.Column).Validation.Add _
Type:=xlValidateList, Formula1:=("=" + Str_ValidationList)
End If
Next
'Loop end actions
Int_PreviousActionFoundColumn = Rg_ActionFound.Column
Set Rg_ActionFound = Rg_TitleRange.Find(CommonDataAndFunctionMod.Str_ActionNameRowLabel, Rg_ActionFound, LookIn:=xlValues, lookAt:=xlWhole, SearchOrder:=xlByRows, MatchCase:=True)
Loop While Rg_ActionFound.Column > Int_PreviousActionFoundColumn
End If
Application.ScreenUpdating = True
Application.EnableEvents = True
I have tested to just comment out the row where the validation is added, so I'm fairly sure that row is the time consumer (mostly). I would take any suggestions.
Thank you in advance!
After some tries I ended up redoing the code so that this routine is run on certain other events instead, hence removing the loading time on start up. The validations are updated only when needed now.
Thank you all for your suggestions!
As you used Loop inside a loop will always slows down the code. think of different algorithm try to use Exit Loop and Exit Do When to cut down the looping time.

Parts of an unsorted list into a drop down

I am trying to create a data validation drop down cell that displays a list of values pulled from a much larger list, but only the ones where the lookup value meet certain requirements. This would be like the SUMIF function that only adds the values where the lookup value meet certain requirements. Here is an example of my list:
V F
Apples x
Bananas x
Tangerines x
Tomatoes x x
Broccoli x
Pears x
Kiwis x
Plums x
Water melon x
Squash x x
I want only the ones with an "x" in the first column to display in the drop down.
Tomatoes
Broccoli
Squash
Also the original list can't be sorted. I am fine with using macros if that would work. I am using Excel 2010.
If you want a range of valid entries without blanks to use as a list for data validation, I suggest something like:
=INDEX($A$2:$A$11,SMALL(IF($B$2:$B$11<>"",ROW($A$2:$A$11)-ROW($A$2)+1),ROWS(C$2:C2)))
entered with Ctrl+Shift+Enter
There is about 20 minutes of explanation at https://www.youtube.com/watch?v=6PcF04bTSOM.
Without using VBA, you could create a copy of the list that is filtered. You can then reference the cells in that copy when you use data validation.
For example, you could do the following steps for your example above:
Apply a filter to the list where only those showing an x in the first column are showing. Copy the filtered list, then paste to another spot on the worksheet. Turn off the filter on the list, so it returns to normal. Go to the cell that you want to add a validation drop down to, and select data validation. Select list, then reference the copied list.
Using VBA, you could use this as a starter. The key is the Range.Validation method, which is explained in detail here. This reads your list in column A, finding those with an "x" in column B, and puts that in a validation list in cell E1.
Dim myvalidation_list As String
Dim last_row As Long, current_row As Long
last_row = Cells(Rows.Count, "A").End(xlUp).Row
For current_row = 1 To last_row
If LCase(ActiveSheet.Cells(current_row, 2).Value) = "x" Then
'put in the delimiting "," if the list already has an entry
If myvalidation_list <> "" Then
myvalidation_list = myvalidation_list & ","
End If
'add to the validation list
myvalidation_list = myvalidation_list _
& ActiveSheet.Cells(current_row, 1).Value
End If
Next
With ActiveSheet.Range("E1").Validation
.Delete
.Add Type:=xlValidateList, Formula1:=myvalidation_list
End With

LotusScript: how to iterate numbered fields with for loop

I'm using LotusScript to clean and export values from a form to a csv file. In the form there are multiple date fields with names like enddate_1, enddate_2, enddate_3, etc.
These date fields are Data Type: Text when empty, but Data Type: Time/Date when filled.
To get the values as string in the csv without errors, I did the following (working):
If Isdate(doc.enddate_1) Then
enddate_1 = Format(doc.enddate_1,"dd-mm-yyyy")
Else
enddate_1 = doc.enddate_1(0)
End If
But to do such a code block for each date field didnt feel right.
Tried the following, but that isnt working.
For i% = 1 To 9
If Isdate(doc.enddate_i%) Then
enddate_i% = Format(doc.enddate_i%,"dd-mm-yyyy")
Else
enddate_i% = doc.enddate_i%(0)
End If
Next
Any suggestions how to iterate numbered fields with a for loop or otherwise?
To iterate numbered fields with a for loop or otherwise?
valueArray = notesDocument.GetItemValue( itemName$ )
however do you know that there is a possibility to export documents in CSV format using Notes Menu?
File\Exort
Also there is a formula:
#Command([FileExport]; "Comma Separated Value"; "c:\document.csv")
Combined solution of Dmytro, clarification of Richard Schwartz with my block of code to a working solution. Tried it as an edit on solution of Dmytro, but was rejected.
My problem was not only to iterate the numbered fields, but also store the values in an iterative way to easily retrieve them later. This I found out today trying to implement the solution of Dmytro combined with the clarification of Richard Schwartz. Used a List to solve it completely.
The working solution for me now is:
Dim enddate$ List
For i% = 1 To 9
itemName$ = "enddate_" + CStr(i%)
If Isdate(doc.GetItemValue(itemName$)) Then
enddate$(i%) = Format(doc.GetItemValue(itemName$),"dd-mm-yyyy")
Else
enddate$(i%) = doc.GetItemValue(itemName$)(0)
End If
Next

Excel Mac VBA Loop Through Cells and reset some values

I currently have a worksheet that I have multiple people filling out every day. There are 4 columns that the users fill out: C, E, H, & J (all numerical values, one row per day of the month.)
The users fill in C, E, & H every day no matter what, but a lot of days there is no value to put in column J. I need the value in J to be set to 0 if the user doesn't enter anything. Of course it would be easier to just have the users enter 0, but I'm working with a complicated group of people here.
Anyway, I want to use a macro that runs automatically when the user clicks the save button (before it actually saves, of course), and have it do the following: (I am more familiar with php, so I'm just typing this out how I'm familiar - I'm sure my syntax is incorrect)
Foreach Row
If "column A" != "" {
If "column J" != "" {
//Everything is good, continue on...
} else {
CurrentRow.ColumnJ.value == 0
}//Value has been set - continue loop
}
//column A is blank, this day hasn't come yet - quit looping here
End Foreach
If anyone could help me out with this I'd appreciate it. With some research, this is what I've come up with so far, and now I'm stuckā€¦
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim curCell As Range
'Labor Flow Sheet'.Select
For Each curCell in Range( ???? )
If curCell.Value = "" Then
???????
End If
Next curCell
End Sub
Thanks in advance!
See this link about finding the right range, and as for the question marks inside the If statement, you would want to put
curCell.Value = 0
For the question marks in your statement
For Each curCell in Range( ???? )
Solution 1:
To find the full range you're working with, you'll need to use a column that is filled out each day. You mentioned columns C, E, and H were filled out every day. Using one of those columns (let's pick C for the example here), you could find the range by using the .end method. This goes out either up down left or right from a range until it doesn't find any data. So,
Range("J1", Range("C1").End(xlDown)).Select
will select all cells from J1 (or whatever column is the last in your sheet) to the bottom-most cell containing data in column C, automatically.
Solution 2:
Manually put in the range. For example, to choose A1 to J300:
Range("A1", "J300").Select

Search WebList for particular item count from Excel sheet

I need a help in VBScript or either in QTP for the below case.
For example:
I have nearly 40 items in the weblist. I have only one item in the Excel sheet that is one among the 40 in the weblist. If I run the script, the one in the Excel should be select in the weblist. How do I perform this? I tried many scenarios, but couldn't get it to work.
Below are some of the sample pieces of code I tried in QTP:
ocount=Browser("name:=brw").Page("title:=brw").WebList("htmlid:=tabContainerBrandSite_123&rtyoh").GetROProperty("items count")
msgbox ocount
var7=mySheet2.Cells(2,"C")
For k=2 to ocount
ocount2=Browser("name:=brw").Page("title:=brw").WebList("html id:=tabContainerBrandSite_123&rtyoh").GetItem(k)
msgbox ocount2
merchantName = DataTable("Merchant_Name","Global") 'an example if value is saved in global sheet
items_count = Browser("Sarit").Page("Sarit_2").WebList("txtVendorCode").GetROProperty("Items Count") 'This will get all the items from your weblist.
i = 1
Do
webListName = Browser("Sarit").Page("Sarit_2").WebList("txtVendorCode").GetItem(i)
'this will get first value from the web list
If merchantName = webListName Then 'comparing first value from your value from global sheet
Browser("Sarit").Page("Sarit_2").WebList("txtVendorCode").Select(i) 'selects that value
Exit do 'because it has found your only value from the local sheet, it exits
else
i = i + 1
End If
Loop While i <= items_count

Resources