Reputation: 11
I have a script that successfully creates a layout variant. I choose the columns that I would like to be in the report by choosing the row number of where the column name is in the list, like this:
session.findById("wnd[1]/usr/tabsG_TS_ALV/tabpALV_M_R1/ssubSUB_DYN0510:SAPLSKBH:0620/cntlCONTAINER1_LAYO/shellcont/shell").selectedRows = "142"
Since it is possible that sometime in the future, my item in row 142 could move up or down the list, I would like to pick it by its name, in this case the name, "Order"
. I've tried various methods using .select
or .selected
, but have not found anything that works. Ideally, it would look something like this:
session.findById("wnd[1]/usr/tabsG_TS_ALV/tabpALV_M_R1/ssubSUB_DYN0510:SAPLSKBH:0620/cntlCONTAINER1_LAYO/shellcont/shell").selectedName = "Order"
Is anything like this possible?
Upvotes: 0
Views: 4567
Reputation: 1304
The previous solutions work only if the layouts are visible in the list, otherwise if you have hundreds of layouts there, as it was in my case, it will fail to work.
Filters to the rescue:
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectColumn "VARIANT"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").contextMenu
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectContextMenuItem "&FILTER"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").text = "/ZSD52LAM"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 1
session.findById("wnd[2]").sendVKey 0
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").clickCurrentCell
By filtering the Layouts list column, we can directly target the layout we're interested it, regardless how many we have there.
You're welcome.
Upvotes: 0
Reputation: 1
I needed to do this as well, because I needed specific columns only in my layout. So instead, I chose my layout, saved it as a variant, then just called to get the layout. Pretty much the same method as from joe but looking for layout variant instead of column fields.
'open layout list
session.findById("wnd[0]/mbar/menu[5]/menu[2]/menu[1]").Select
'set list of all layouts
Set Layout = session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell")
'find Layout name in all the rows and choose it
iRows = Layout.RowCount()
For i = 0 To iRows - 1
LayoutVariant = Layout.getCellValue(i, "VARIANT")
If LayoutVariant = "/YourLayoutNameGoesHere" Then
Layout.currentCellRow = i
Layout.clickCurrentCell
Exit For
End If
Next
End Sub
modified this from this SAP thread
Upvotes: 0
Reputation: 11
It is possible to select from an SAP listbox without knowing which row contains the field that you want to use. Basically, you can step through the rows by row number and see if the current row's value is equal to field you want to display. Since SAP uses multiple processes for this, this solution only works for simple listboxes. I have solutions for listboxes displaying tables. If want to see that solution, let me know.
When I first wrote this code, I started at row zero each time and went towards the bottom of the listbox to find each subsequent item. This is a later version the process changes the search direction from the current row based predicting if the next field name is above or below alphabetically.
Create an object for the SAP listbox:
Public gridView As Object
Put the SAP listbox into gridView and call the subroutine to look through the items in the listbox. The named range "mnHead" is the location of the first field name desired in the layout with the rest following in the same column.
Set gridView = session.findById("wnd[1]/usr/tabsG_TS_ALV/tabpALV_M_R1/ssubSUB_DYN0510:SAPLSKBH:0620/cntlCONTAINER1_LAYO/shellcont/shell")
Call getFields("mnhead")
The subroutine:
Sub getFields(fNames As String)
Dim i, j, k, m, n As Integer
Dim str1, str2, str3, str4, str5 As String
j = 0 ' j is counter for loop - it points at the current desired field name
k = 0 ' k is start for the item to check
m = 1 ' m is counter step 1 for alpha, -1 for anti-alpha
str3 = "0000000000000000" ' padding for later compare
n = gridView.rowcount - 1 ' n = the number of rows in the listbox, it starts at row zero, so take one away
Do While Range(fNames).Offset(j, 0) <> "" ' loop to get all the fields
str2 = Range(fNames).Offset(j, 0) ' put the desired field name in string var str2
For i = k To n Step m ' loop through the rows in the listbox
gridView.currentCellRow = i ' scroll to the row number i
gridView.SetCurrentCell i, "SELTEXT" ' select the item in row i
If gridView.GetCellValue(i, "SELTEXT") = str2 Then ' get the value in row I and see if it's the same as the field name wanted
str1 = str2 ' it's the same so save the heading in temp variable str1
Exit For ' found so exit the loop
End If
Next i
If i >= gridView.rowcount Then ' if we went all the way to the bottom with no match, give a message
MsgBox ("Match not found for " & str2)
Stop
End If
gridView.doubleClickCurrentCell ' double click on the row to send it to the left listbox
str4 = Left(LCase(Left(Replace(str2, " ", ""), 14)) & str3, 15)
str5 = Left(LCase(Left(Replace(Range(fNames).Offset(j + 1, 0), " ", ""), 14)) & str3, 15)
If str4 <= str5 Then ' continue alphabetically the list in next search
If i < 0 Then k = 0 Else k = i ' check to see if we're below the first item and reset to first if we are
m = 1 ' count step is plus one
n = gridView.rowcount - 1 ' endpoint is the end of the alphabet
Else
If i > gridView.rowcount - 1 Then k = gridView.rowcount - 1 Else k = i ' if we're past the end then reset to the end
m = -1 ' count step is minus one - anti-alpha
n = 0 ' endpoint is the beginning
End If
j = j + 1 ' increment j and reloop
Loop
Upvotes: 0