#excel #vbscript #sap-gui #sap-erp
Вопрос:
У меня проблема с SAP VA02
, когда я хочу определить строку строки, в которой находится определенная метка. В этом случае надпись/текст «Cust. ожидаемая цена».
Я пытаюсь изменить данные рядом с этой строкой, проблема в том, что это не всегда одна и та же строка, иногда это 16, 18 и т. Д.
Я пытаюсь найти способ просмотреть каждую строку в столбце 2 в структуре, прочитать текст и найти, в какой строке находится метка, а затем использовать строку в качестве переменной, чтобы вставить цену в правильную ячейку. Я вставил ниже некоторый функциональный код.
То, что я делаю, — это ввод правильной цены здесь: session.findById("wnd[0]/usr/tabsTAXI_TABSTRIP_ITEM/tabpT5/ssubSUBSCREEN_BODY:SAPLV69A:6201/tblSAPLV69ATCTRL_KONDITIONEN/txtKOMV-KBETR[3,16]").Text = Price
Мой главный вопрос в том, как прочитать, например, какой текст находится в каждой ячейке session.findById("wnd[0]/usr/tabsTAXI_TABSTRIP_ITEM/tabpT5/ssubSUBSCREEN_BODY:SAPLV69A:6201/tblSAPLV69ATCTRL_KONDITIONEN/txtKOMV-KBETR[2,16]")
Я, вероятно, смогу выяснить остальное оттуда. Я не смог найти много информации об этой конкретной структуре, любой вклад приветствуется. Я также опубликую скриншот страницы для справки. Спасибо!
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/tabpT2/ssubSU" _
amp; "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/tabpT5/ssubSU" _
amp; "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/tabpT11").Select
session.findById("wnd[0]/usr/tabsTAXI_TABSTRIP_ITEM/tabpT11/ssubSU" _
amp; "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
Комментарии:
1. Я думаю, вы спросите, как найти номер строки элемента управления таблицей (имя используемого вами элемента), в котором расположен данный текст, правильно ли это? NB: вы можете упростить чтение своего сценария, используя переменную (две строки могут быть сокращены до:
Set tbl = session.findById("wnd[0]/usr/tabsTAXI_TABSTRIP_OVERVIEW/tabpT2/ssubSUBSCREEN_BODY:SAPMV45A:4401/subSUBSCREEN_TC:SAPMV45A:4900/tblSAPMV45ATCTRL_U_ERF_AUFTRAG") : tbl..verticalScrollbar.Position = Scroll : tbl.getAbsoluteRow(Item).Selected = True
; NB: здесь используются двоеточия из-за ограничения многострочного комментирования переполнения стека)2. Я отредактировал ваш вопрос, чтобы сделать сценарий более разборчивым (переменная разделенные строки)
3. Да, я ищу номер строки, в которой находится текст.
Ответ №1:
Вот как ссылаться на значение ячейки в данной строке и заданном столбце, которые указаны в переменных:
row = 0
column = 1
cellText = session.findById(".../tblXXXXX/columnFieldName[" amp; column amp; "," amp; row amp; "]").Text
Другим решением является использование метода getCell для объекта управления таблицей:
cellText = session.findById(".../tblXXXXX").GetCell(row,column).Text
ПРИМЕЧАНИЕ: обратите внимание, что аргументы строк и столбцов переключаются.
Чтобы узнать, какие значения использовать для «…/tblXXXXX/columnFieldName […], проще всего записать сценарий, просто переместив курсор в нужный столбец. Сгенерированный скрипт вернет что-то подобное (протестируйте с помощью демонстрационной программы 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
Номер строки соответствует порядку среди видимых строк, начиная с 0 (0 = первая видимая строка). Последняя видимая строка имеет число, равное свойству управления таблицей VisibleRowCount
минус 1. К строкам, которые не видны (вверху и внизу), можно получить доступ, выполнив вертикальную прокрутку сценария.Дополнительные сведения о программной прокрутке см. в следующей главе.
Номер столбца зависит от порядка столбцов, отображаемых в элементе управления таблицей, независимо от того, какие столбцы видны сразу или видны после горизонтальной прокрутки. Сценарию не нужно выполнять горизонтальную прокрутку, чтобы считывать значения невидимых столбцов. 0-крайний левый столбец, а крайний правый столбец имеет число, равное двум свойствам элемента управления таблицей Columns.Count
минус 1.
- Список столбцов и их порядок могут варьироваться в зависимости от конфигурации элемента управления активной таблицей. Возможно, вы захотите определить номер столбца на основе имени столбца во время выполнения, для этого см. главу ниже.
- Могут быть и другие столбцы, предлагаемые с помощью функции администратора управления таблицами, с установленным флажком «скрыто». Сценарии SAP GUI полностью игнорируют эти столбцы. Если вам нужно работать с ними, вы должны вызвать метод управления таблицей
ConfigureLayout
для отображения экрана администратора, а затем вы можете работать с настройками, как с любым другим экраном.
Прокручивание строк
Для элемента управления таблицей сценарий SAP GUI знает только данные в строках, которые в данный момент видны на экране, поскольку по соображениям производительности серверная программа ABAP отправляет только эти строки на интерфейс. Сценарии графического интерфейса SAP не могут знать значения из невидимых строк. Требуется, чтобы сценарий прокручивался вертикально, чтобы получить другие строки. Внимание, прокрутка означает перезагрузку всего экрана, поэтому элементы экрана необходимо создать заново. В следующем примере прокручивается весь список, чтобы отобразить все значения в первом столбце (использование демонстрационной программы 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 amp; tbl.GetCell(visibleRow,0).Text amp; 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
Обратите внимание, что этот пример подходит для небольшого количества страниц. Во многих других ситуациях существует гораздо больше страниц, для такого действия, как поиск строки, содержащей заданное значение, было бы гораздо эффективнее нажать существующую кнопку, чтобы выполнить внутренний поиск этого значения. Сразу же отобразится нужная страница.
Определите номер столбца по имени столбца во время выполнения
Как объяснялось выше, номер столбца может варьироваться в зависимости от порядка столбцов и скрытых столбцов. Если они изменяются неопределенным образом во время выполнения, следующий код позволяет определить номер столбца на основе имени столбца (обратите внимание, что префикс нижнего регистра имени поля должен быть удален, например «ctxt» в «ctxtDEMO_CONN-CITYFROM»), но он работает только в том случае, если есть по крайней мере 1 строка (решение не найдено, если оно необходимо, когда элемент управления таблицей пуст).:
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
Приложение
Для получения дополнительной информации, пожалуйста, обратитесь к документации «Объекта GuiTableControl» в библиотеке SAP.
ПРИМЕЧАНИЕ: если вы посмотрите на другие вопросы, имейте в виду, что элемент управления таблицей ( GuiTableControl
) совершенно не связан с представлением сетки ( GuiGridView
), поэтому не путайте.