SAP系统表格中指定的行进行某项清算操作,要求只选择金额汇总(黄行)为负数且为0的项目进行清算,效果如图:SAP中有一个选择指定行的方法:importsysimportwin32com.clientSapGuiAuto=win32com.client.GetObject("SAPGUI")application=SapGuiAuto.GetScriptingEngineconnection=application.Children(0)session=connection.Children(0)#连接SAPServicee=session.findByID('wnd[0]/usr/cntlGRID1/shellcont/shell')#获取SAP表e.selectedRows='1'如果要选择多个行,直接写:e.selectedRows='1,2,3,5'如果是连续的行可以更简单:e.selectedRows='1-5'运行一下看看效果:完美,就知道了选中的行是从0开始的。需要注意的是,如果表很大,表后面的部分是不会加载的,所以运行e.select直接edRows是没有作用的,所以必须翻页,翻到最后一页的时候,可以选择所有需要的行。翻页部分代码如下:importubpa.ikeyboardasikeyboardrow=e.rowCount#行数print(row//44)#翻页次数,44为当前页显示的行数jinrange(row//44):ikeyboard.key_send_cs(text='{PGDN}',waitfor=10)time.sleep(0.4)现在有更好的翻页方法:http://support.isearch.com.cn...所以还是建议少用pagedown翻页。下面开始设计算法:我们需要三个列表,一个是存款汇总所在的行数,一个是每笔存款汇总的标记(这里的金额为负数,0标记为a)负号,金额为正的记为正号),一个索引,存放所有的负号。分别将它们命名为index、type_index和need_index。①先根据凭证号遍历全表,将凭证号为空行的索引添加到第一个列表中。这是汇总金额的行数:foriinrange(e.rowCount-1):value=e.getCellValue(i,e.columnOrder(0))ifvalue=='':index.append(i)②然后标记每个总和并将其存储在第二个列表中:foriinindex:ife.getCellValue(i,e.columnOrder(12)).endswith('-')ore.getCellValue(i,e.columnOrder(12))=='0.00':type_index.append('-')else:type_index.append('+')③接下来只判断第二个列表中的mark,如果是负数,取两者之间的值thisindex和previousindex,并将所有符合条件的值添加到第三个列表中:iftype_index[0]=='+':foriinrange(len(type_index)):iftype_index[i]=='-':ifindex[i-1]+1==index[i]-1:#如果两个总和之间只有一行need_index.append(str(index[i-1]+1))else:need_index.append(str(index[i-1]+1)+'-'+str(index[i]-1))eliftype_index[0]=='-':#如果情况稍微复杂一点如果index[0]==1:#There在第一个金额摘要之前只有一行need_index.append('0')else:need_index.append('0-'+str(index[0]-1))foriinrange(len(type_index)-1):iftype_index[i+1]=='-':ifindex[i]+1==index[i+1]-1:need_index.append(str(index[i]+1))else:need_index.append(str(index[i]+1)+'-'+str(index[i+1]-1))④need_index现在包含所有需要选择的行,然后转成我们需要的字符串格式:e.selectedRows=','.join(need_index)这个算法的时间复杂度还是有点高,如果有更好的idea也可以分享完整代码importsysimportwin32com.clientimporttimeimportubpa.ikeyboardasikeyboardSapGuiAuto=win32com.client.GetObject("SAPGUI")application=SapGuiAuto.GetScriptingEngineconnection=application.Children(0)session=connection.Children(0)#连接SAP服务e=session.findByID('wnd[0]/usr/cntlGRID1/shellcont/shell')#获取SAP表单f=e.columnCount#列号row=e.rowCount#行号print('tablerownumber为{},表格列数为{}'.format(row,f))print('-'*20)print(int(row/44))#在范围内为j翻页的次数(int(row/44)):ikeyboard.key_send_cs(text='{PGDN}',waitfor=10)time.sleep(0.4)index=[]#金额汇总的行数type_index=[]#每个金额汇总的正负值,如果为0,也标记为负值need_index=[]#所有负数的索引valuesforiinrange(e.rowCount-1):value=e.getCellValue(i,e.columnOrder(0))ifvalue=='':index.append(i)print('每个索引所在的位置汇总的金额为{},客户总数为{}'.format(index,len(index)))print('-'*20)foriinindex:ife.getCellValue(i,e.columnOrder(12)).endswith('-')或e.getCellValue(i,e.columnOrder(12))=='0.00':type_index.append('-')else:type_index.append('+')iftype_index[0]=='+':foriinrange(len(type_index)):iftype_index[i]=='-':ifindex[i-1]+1==index[i]-1:need_index.append(str(index[i-1]+1))else:need_index.append(str(index[i-1]+1)+'-'+str(index[i]-1))eliftype_index[0]=='-':如果index[0]==1:need_index.append('0')else:need_index.append('0-'+str(index[0]-1))foriinrange(len(type_index)-1):iftype_index[i+1]=='-':如果index[i]+1==index[i+1]-1:need_index.append(str(index[i]+1))else:need_index.append(str(index[i]+1)+'-'+str(index[i+1]-1))e.selectedRows=','.join(need_index)免费下载试用:https://support.i-search.com.cn/
