I have a problem with SAP VA02 where I want to identify the row line in which a specific label is. In this case the label/text is "Cust. expected price".
I am trying to change the data next to this row, problem is that it is not always the same row, sometimes it is 16, 18, etc.
I am trying to find a way to loop through each row in column 2 in the structure, read the text, and find which row the label is in, then use the row as a variable to paste the price in the correct cell. I have pasted some functioning code below.
What I am doing is inputting the correct price here:
session.findById("wnd[0]/usr/tabsTAXI_TABSTRIP_ITEM/tabpT\05/ssubSUBSCREEN_BODY:SAPLV69A:6201/tblSAPLV69ATCTRL_KONDITIONEN/txtKOMV-KBETR[3,16]").Text = Price
My main question is how to read what text is in each cell for example session.findById("wnd[0]/usr/tabsTAXI_TABSTRIP_ITEM/tabpT\05/ssubSUBSCREEN_BODY:SAPLV69A:6201/tblSAPLV69ATCTRL_KONDITIONEN/txtKOMV-KBETR[2,16]")
I can probably figure out the rest from there. I haven't been able to find much regarding this specific structure, any input is appreciated. I will also post a screenshot of the page for reference. Thank you!
Sub OrderRelease()
Dim Order As String
Dim RowCount As Integer
Dim Item As Integer
Dim sh As Worksheet
Dim rw As Range
Dim Sroll As Integer
Dim Price As Double
On Error Resume Next
RowCount = 0
Set sh = ActiveSheet
For Each rw In sh.Rows
If sh.Cells(rw.Row, 6).Value = "" Then
Exit For
End If
RowCount = RowCount + 1
Next rw
If Not IsObject(SAPGuiApp) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set SAPGuiApp = SapGuiAuto.GetScriptingEngine
End If
If Not IsObject(Connection) Then
Set Connection = SAPGuiApp.Children(0)
End If
If Not IsObject(SAP_session) Then
Set session = Connection.Children(0)
End If
If IsObject(WScript) Then
WScript.ConnectObject SAP_session, "on"
WScript.ConnectObject SAPGuiApp, "on"
End If
session.findById("wnd[0]").maximize
session.findById("wnd[0]/tbar[0]/okcd").Text = "/nva02"
session.findById("wnd[0]").sendVKey 0
For i = 2 To RowCount
Order = Cells(i, "F")
session.findById("wnd[0]/usr/ctxtVBAK-VBELN").Text = Order
session.findById("wnd[0]/usr/ctxtVBAK-VBELN").caretPosition = 9
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[1]/tbar[0]/btn[0]").press
Continue:
Item = Cells(i, "G") / 10 - 1
Scroll = Item - 1
Price = Cells(i, "H")
Set sub = session.findById("wnd[0]/usr/tabsTAXI_TABSTRIP_OVERVIEW/tabpT\02/ssubSU" _
& "BSCREEN_BODY:SAPMV45A:4401/subSUBSCREEN_TC:SAPMV45A:4900")
Set tbl = sub.findById("tblSAPMV45ATCTRL_U_ERF_AUFTRAG")
tbl.verticalScrollbar.Position = Scroll
tbl.getAbsoluteRow(Item).Selected = True
tbl.findById("txtVBAP-POSNR[0,8]").SetFocus
tbl.findById("txtVBAP-POSNR[0,8]").caretPosition = 4
sub.findById("subSUBSCREEN_BUTTONS:SAPMV45A:4050/btnBT_PKON").press
Set tbl2 = session.findById("wnd[0]/usr/tabsTAXI_TABSTRIP_ITEM/tabpT\05/ssubSU" _
& "BSCREEN_BODY:SAPLV69A:6201/tblSAPLV69ATCTRL_KONDITIONEN")
tbl2.verticalScrollbar.Position = 8
'The below line is what I need to find. In this case, Cust. expected price would be 2,16,
'but I have not found a way to actually read the text in that cell.
tbl2.findById("txtKOMV-KBETR[3,16]").Text = Price
tbl2.findById("txtKOMV-KBETR[3,16]").SetFocus
tbl2.findById("txtKOMV-KBETR[3,16]").caretPosition = 16
session.findById("wnd[0]/usr/tabsTAXI_TABSTRIP_ITEM/tabpT\11").Select
session.findById("wnd[0]/usr/tabsTAXI_TABSTRIP_ITEM/tabpT\11/ssubSU" _
& "BSCREEN_BODY:SAPMV45A:4456/cmbVBAP-ABGRU").Key = " "
session.findById("wnd[0]/tbar[0]/btn[3]").press
session.findById("wnd[0]/usr/btnBUT2").press
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[0]").sendVKey 0
If Cells(i, "F") = Cells(i + 1, "F") Then
i = i + 1
GoTo Continue
End If
session.findById("wnd[0]").sendVKey 11
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/btnSPOP-VAROPTION1").press
Next i
End Sub
Here is how to refer to a value of a cell in a given row and a given column, which are both provided in variables:
row = 0
column = 1
cellText = session.findById(".../tblXXXXX/columnFieldName[" & column & "," & row & "]").Text
Another solution is to use the method GetCell on the Table Control object:
cellText = session.findById(".../tblXXXXX").GetCell(row,column).Text
NB: notice that row and column arguments are switched.
To know what values to use for ".../tblXXXXX/columnFieldName[...], the easiest way is to record a script, by simply moving the cursor to the desired column. The generated script will return something like that (test with the demo program DEMO_DYNPRO_TABCONT_LOOPFLIGHTS):
session.findById("wnd[0]/usr/tblDEMO_DYNPRO_TABCONT_LOOPFLIGHTS/ctxtDEMO_CONN-CITYFROM[2,1]").setFocus
session.findById("wnd[0]/usr/tblDEMO_DYNPRO_TABCONT_LOOPFLIGHTS/ctxtDEMO_CONN-CITYFROM[2,1]").caretPosition = 1
The row number corresponds to the order among the visible rows, starting from 0 (0 = first visible row). The last visible row has the number equals to the Table Control property VisibleRowCount minus 1. The rows which are not visible (above and below) can be accessed by making your script scroll vertically, for more information about scrolling programatically see below chapter.
The column number is based on the order of columns shown in the Table Control, whatever the columns are immediately visible or visible after horizontal scrolling. The script doesn't need to perform horizontal scrolling to read the values of non-visible columns. 0 is the leftmost column, and the rightmost column has the number equals to the two properties of the Table Control Columns.Count minus 1.
The list of columns and their order may vary according to the active Table Control configuration. You may wish to determine the column number based on the column name at run time, for that see below chapter.
There may be other columns proposed via the Table Control administrator function, with the "hidden" checkbox selected. SAP GUI Scripting completely ignores these columns. If you need to work with them, you must call the table control method ConfigureLayout to display the administrator screen, and then you can work with the settings as you do with any other screen.
Scrolling the rows
For a Table Control, SAP GUI Scripting knows only the data in the lines which are currently visible on the screen, because for performance reason the backend ABAP program sends only these lines to the frontend. SAP GUI Scripting can't know the values from the invisible lines. It's required that the script scrolls vertically to obtain the other rows. Attention, scrolling means the reloading of the whole screen, so the screen elements need to be re-instantiated. The following example scrolls the whole list to display all the values in the first column (use of the demo program DEMO_DYNPRO_TABCONT_LOOPFLIGHTS):
Set tbl = session.findById("wnd[0]/usr/tblDEMO_DYNPRO_TABCONT_LOOPFLIGHTS")
' Make the first row visible (show the top of the list) -> that calls the back-end system and screen is reloaded.
' ATTENTION: when the back-end is called, to continue working with screen elements, they must be re-instantiated.
tbl.VerticalScrollbar.Position = 0
TextsOfAllCellsInColumnZero = ""
Do While True
' Re-instantiate the Table Control element (mandatory each time the back-end is called)
Set tbl = session.findById("wnd[0]/usr/tblDEMO_DYNPRO_TABCONT_LOOPFLIGHTS")
visibleRow = 0
currentScrollbarPosition = tbl.VerticalScrollbar.Position
While visibleRow < tbl.VisibleRowCount And currentScrollbarPosition <= tbl.VerticalScrollbar.Maximum
TextsOfAllCellsInColumnZero = TextsOfAllCellsInColumnZero & tbl.GetCell(visibleRow,0).Text & Chr(10)
visibleRow = visibleRow + 1
currentScrollbarPosition = currentScrollbarPosition + 1
Wend
If currentScrollbarPosition > tbl.VerticalScrollbar.Maximum Then
Exit Do
End If
tbl.VerticalScrollbar.Position = currentScrollbarPosition
Loop
MsgBox TextsOfAllCellsInColumnZero
Note that this example is suitable to a small number of pages. In many other situations, there are many more pages, for an action like searching a line containing a given value, it would be much more performing to click an existing button to perform a back-end search of this value. The right page would be immediately be displayed.
Determine the column number from the column name at run time
As explained above, the column number may vary depending on the order of columns and on hidden columns. If they vary in an undetermined way at run time, the following code allows to determine the column number based on the column name (note that the lower case prefix of the field name is to be removed, like "ctxt" in "ctxtDEMO_CONN-CITYFROM"), but it works only if there's at least 1 row (no solution found if it's needed when the Table Control is empty):
Set tbl = session.findById("wnd[0]/usr/tblDEMO_DYNPRO_TABCONT_LOOPFLIGHTS")
column = GetColumnNumberByName(tbl,"DEMO_CONN-CITYFROM")
msgbox tbl.GetCell(row,column).text
Function GetColumnNumberByName( TableControl, ColumnName )
If TableControl.Rows.Count > 0 Then
For i = 0 To TableControl.Columns.Count - 1
If TableControl.Columns(i)(0).Name = ColumnName Then
GetColumnNumberByName = i
Exit Function
End If
Next
End If
GetColumnNumberByName = -1
End Function
Appendix
For more information, please refer to the documentation of the "GuiTableControl Object" in the SAP Library.
NB: if you look at other questions, be aware that a Table Control (GuiTableControl) is completely unrelated to a Grid View (GuiGridView), so don't be confused.
I'm writing some VBA code for a user form. The values are selected in a listbox on the left (LB_Participants). Then "select" is pressed and the values are copied to a listbox on the right (LB_Output). I then want VBA to go through all these items seperatly in the LB_Output and look up other associated data from another worksheet. Problem I'm having is that somethimes the values are not selected. I check it with a messagebox and from time to time its blank. Then no associated data can be retrieved ofcourse.
Before starting to fill in the userform, if I just click once on LB_Output (even without selecting any value) I don't have this problem. Many people will be using the userform so I don't want to explain tot them that they have to click first on the listbox before continuing... Is there something I'm not doing right?
Blank Msgbox
Dim ListCount As Integer
Dim z As Integer
ListCount = UserForm2.LB_Output.ListCount
For z = 0 To ListCount - 1
UserForm2.LB_Output.Selected(z) = True
TextString = UserForm2.LB_Output.Value
MsgBox (TextString)
'Split Participants into seperate names and copy them to data sheet
WArray() = Split(TextString, ";")
For Counter = LBound(WArray) To UBound(WArray)
Dim LRNames As Integer
If IsEmpty(Sheets("Data").Range("A1")) = True Then
LRNames = 0
Else
LRNames = Sheets("Data").Range("A" & Application.Rows.Count).End(xlUp).Row
End If
Strg = WArray(Counter)
Sheets("Data").Cells(LRNames + 1, 1) = Trim(Strg)
Next Counter
Next z
Not sure I understand, but think you want to loop through all the items in LB_Output and process them regardless if selected or not - all the selection was done in the other listbox and those items moved to LB_Output.
This does not explicitly select each item, simply gets data from it.
For z = 0 to UserForm2.LB_Output.Listcount -1
' If you want to select the item to show 'progress' through the list,
' uncomment ...
' LB_Output.listindex = z
' The next line will still work as is
TextString = UserForm2.LB_Output.List(z)
'// Do processing with this item
Next
I'm working on a loop that finds the adjacent value based on a looped additem list combobox in userform. First looped code works just perfect. second doesnt find its value.
I've tried changing formatting in the cell where the value is stored. i've tried to switch the userform box with the working one. That makes them both malfunction.
'Works without a problem
Private Sub REQUESTED_Change()
i = 1
kto = FORM.REQUESTED
Do While (Worksheets("DATA").Cells(i, 1) <> "")
i = i + 1
If Worksheets("DATA").Cells(i, 1) = kto Then
DEPARTEMENT.Text = Worksheets("DATA").Cells(i, 2)
End If
Loop
End Sub
'Doesn't work. It loops with the correct value, but doesnt find itself
Private Sub CUSTNR_Change()
i4 = 1
kSto = FORM.CUSTNR
Do While (Worksheets("DATA").Cells(i4, 6) <> "")
i4 = i4 + 1
If Worksheets("DATA").Cells(i4, 6) = kSto Then
NAZWA.Text = Worksheets("DATA").Cells(i4, 7)
End If
Loop
End Sub
It should loop based on the value typed/listed in the userform combobox, find the row its in, and based on that i value, get the adjacent value in the cell next to it in the same row.
I don't know how to take action with the VBA Userform here.
I have a userform which allows users add more textboxes and type the value to the textboxes. I want to copy those values from each additional textbox to separate cells. This is what I did, but not working.
Label "Add textbox after clicking_THIS ONE IS WORKING"
Private Sub CommandButton2_Click()
x = Me.Controls.count + 1
Set xx = Controls.Add("Forms.TextBox.1", "CtrlName" & x)
xx.Top = x * 20 - 108
xx.Left = 396
xx.Width = 288
End Sub
Label "Get value from textboxes to cell_THIS IS NOT WORKING"
Private Sub CommandButton1_Click()
Dim count as Integer
Dim i as Integer
count = Me.Controls.count - 9 ("I have 9 other controls, so need to - 9 to count the number of textboxes")
For i = 1 To count
Cells(i, 1).Select
ActiveCell.Value = Me.Controls("TextBox" & i).Value
Next i
End Sub
The problem is the Me.Controls ("TextBox" & I).Value. I tried different funtions here, but still couldn't solve that.
You have named your textboxes CtrlName10, CtrlName11, etc. You must use those names, not TextBox1 etc. Which means that the value is Me.Controls("CtrlName" & (i + 9)).Value.
Hint: In error box saying Could not find the specified object press the button Debug. This will return you to the code editor, with the offending statement highlighted, and you can examine the variables in the Locals pane (on the View menu).
i need to add a number to textbox for everytime a specific item that was used to a cell in excel using vb. For example, for everytime the word "Time" is selected from the combobox1, it must add 1 to cell B2. and if "Time" is selected again. it must add 1 again to cell B2. Then cell B2 must have "2" in it
ive tried this, but it doesnt seem to work:
Dim Scrap As String
Scrap = ComboBox1.Text
Select Case Scrap
Case "Aluminium"
worksheet2.Cells(4, 3) = +AmountBox.Text
worksheet2.Cells(4, 4) = +KiloBox.Text
worksheet2.Cells(4, 2) = +1 'adds 1 for each time this type of scrap is used
end select
Dim Temp as Integer = CInt(worksheet2.Cells(4, 2).Value)
Temp += 1
worksheet2.Cells(4, 2).Value = Temp
Try something like this
This as well can do it:
worksheet2.Cells(4, 2) = (worksheet2.Cells(4, 2).Value + 1)