Excel 在SAP脚本中,是否可以按名称而不是按行位置选择列?

Excel 在SAP脚本中,是否可以按名称而不是按行位置选择列?,excel,vba,sap,Excel,Vba,Sap,我有一个脚本,它成功地创建了一个布局变量。我通过选择列名称在列表中的行号来选择我希望在报告中的列,如下所示: session.findById("wnd[1]/usr/tabsG_TS_ALV/tabpALV_M_R1/ssubSUB_DYN0510:SAPLSKBH:0620/cntlCONTAINER1_LAYO/shellcont/shell").selectedRows = "142" session.findById("wnd[1]/usr/tabsG_TS_ALV/tabpAL

我有一个脚本,它成功地创建了一个布局变量。我通过选择列名称在列表中的行号来选择我希望在报告中的列,如下所示:

 session.findById("wnd[1]/usr/tabsG_TS_ALV/tabpALV_M_R1/ssubSUB_DYN0510:SAPLSKBH:0620/cntlCONTAINER1_LAYO/shellcont/shell").selectedRows = "142"
 session.findById("wnd[1]/usr/tabsG_TS_ALV/tabpALV_M_R1/ssubSUB_DYN0510:SAPLSKBH:0620/cntlCONTAINER1_LAYO/shellcont/shell").selectedName = "Order"
因为有可能在将来的某个时候,我在第142行中的项目会在列表中上移或下移,所以我想根据它的名称来选择它,在本例中是“Order”。我尝试了使用.select或.select的各种方法,但没有找到任何有效的方法。理想情况下,它看起来像这样:

 session.findById("wnd[1]/usr/tabsG_TS_ALV/tabpALV_M_R1/ssubSUB_DYN0510:SAPLSKBH:0620/cntlCONTAINER1_LAYO/shellcont/shell").selectedRows = "142"
 session.findById("wnd[1]/usr/tabsG_TS_ALV/tabpALV_M_R1/ssubSUB_DYN0510:SAPLSKBH:0620/cntlCONTAINER1_LAYO/shellcont/shell").selectedName = "Order"

这样做可能吗

可以从SAP列表框中选择,而不知道哪一行包含要使用的字段。基本上,您可以按行号逐行查看当前行的值是否等于要显示的字段。由于SAP为此使用多个流程,因此此解决方案仅适用于简单的列表框。我有显示表格的列表框的解决方案。如果你想看到解决方案,请告诉我

当我第一次编写这段代码时,我每次都从第0行开始,然后到列表框的底部查找后续的每一项。这是一个更高版本。如果下一个字段名按字母顺序在上或在下,该过程将根据当前行更改搜索方向

为SAP listbox创建一个对象:

    Public gridView As Object
将SAP listbox放入gridView并调用子例程查看listbox中的项目。命名范围“mnHead”是布局中所需的第一个字段名的位置,其余字段名在同一列中

    Set gridView = session.findById("wnd[1]/usr/tabsG_TS_ALV/tabpALV_M_R1/ssubSUB_DYN0510:SAPLSKBH:0620/cntlCONTAINER1_LAYO/shellcont/shell")
    Call getFields("mnhead")
子程序:

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
子getFields(fNames作为字符串)
作为整数的Dim i,j,k,m,n
作为字符串的Dim str1、str2、str3、str4、str5
j=0'j是循环计数器-它指向当前所需的字段名
k=0'k是要检查的项目的开始
m=1'm是α的计数器步骤1,反α的计数器步骤1
str3=“0000000000000000”填充以供以后比较
n=gridView.rowcount-1'n=listbox中的行数,它从第0行开始,所以去掉一行
执行While Range(fNames).Offset(j,0)“”循环以获取所有字段
str2=Range(fNames).Offset(j,0)”将所需的字段名放入字符串var str2中
对于i=k到n,步骤m'通过列表框中的行循环
gridView.currentCellRow=i'滚动至行号i
gridView.SetCurrentCell i,“SELTEXT”选择第一行中的项目
如果gridView.GetCellValue(i,“SELTEXT”)=str2,则“获取第i行中的值,并查看它是否与所需的字段名相同。”
str1=str2'相同,因此将标题保存在临时变量str1中
找到“退出”,因此退出循环
如果结束
接下来我
如果i>=gridView.rowcount,则“如果我们一直到底部,但没有匹配项,请给出一条消息
MsgBox(“未找到匹配项”&str2)
停止
如果结束
gridView.doubleClickCurrentCell'双击该行以将其发送到左侧列表框
str4=左侧(LCase(左侧)(替换(str2,“,”),14))和str3,15)
str5=左(LCase(左(替换范围(fNames).偏移量(j+1,0),“”,“”),14))&str3,15)

如果str4我也需要这样做,因为我只需要在布局中使用特定的列。因此,我选择了我的布局,将其保存为变体,然后调用以获取布局。与joe中的方法几乎相同,但查找布局变量而不是列字段

'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

我们的SAP专家建议我也使用一个变体。不幸的是,在这里创造一个全球变体需要上帝的行动。在收到许多在用户的SAP帐户中构建变体的请求后,我开发了构建方法。构建此算法使宏完全可移植。