Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SAP和Excel:在错误转到内在错误转到内?_Excel_Vba - Fatal编程技术网

SAP和Excel:在错误转到内在错误转到内?

SAP和Excel:在错误转到内在错误转到内?,excel,vba,Excel,Vba,我试图在SAP GUI和Excel电子表格之间来回切换。我有一个表列表,我想在SAP中查看,从SAP中提取数据,粘贴到Excel,然后转到下一个表。如果该表在SAP中不存在,我希望它转到下一个表(该表当前可能不存在,但将来可能存在,我希望它是动态的,我不想硬编码表名) 我已经有一个错误序列开始工作,但是说我们要引用的下一个表也不存在;这个错误必须得到处理 Sub SAPEverything() Application.ScreenUpdating = False Application.Dis

我试图在SAP GUI和Excel电子表格之间来回切换。我有一个表列表,我想在SAP中查看,从SAP中提取数据,粘贴到Excel,然后转到下一个表。如果该表在SAP中不存在,我希望它转到下一个表(该表当前可能不存在,但将来可能存在,我希望它是动态的,我不想硬编码表名)

我已经有一个错误序列开始工作,但是说我们要引用的下一个表也不存在;这个错误必须得到处理

Sub SAPEverything()

Application.ScreenUpdating = False
Application.DisplayAlerts = False

ans = MsgBox("Are you currently logged into SAP?", vbYesNoCancel)

If ans = vbNo Then
    MsgBox ("Please log into SAP, then come back to this macro.")
    Exit Sub
ElseIf ans = vbCancel Then
    Exit Sub
ElseIf ans = vbYes Then
    frmSAP.Show
    frmSAP.Hide

    LastRow = Sheets("Sheet2").Cells(Rows.Count, 19).End(xlUp).Row
    CurrRow = 2

    For i = 2 To LastRow
        Set SapGuiAuto = GetObject("SAPGUI")  'Get the SAP GUI Scripting object
        Set SAPApp = SapGuiAuto.GetScriptingEngine 'Get the currently running SAP GUI
        Set SAPCon = SAPApp.Children(0) 'Get the first system that is currently connected
        Set session = SAPCon.Children(0) 'Get the first session (window) on that connection
        'Start the transaction to view a table
        session.StartTransaction "Transaction"

        session.findById("wnd[0]").maximize
        session.findById("wnd[0]/tbar[1]/btn[16]").press
        session.findById("wnd[0]/tbar[1]/btn[8]").press
        On Error GoTo HandlingIt
        session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").SelectAll
        session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").contextMenu
        session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").selectContextMenuItemByText "Copy Text"

        Workbooks("WorkbookName").Activate
        Sheets("Sheet2").Select
        Cells(CurrRow, 2).Select
        ActiveSheet.Paste
        NewLastRow = Sheets("Sheet2").Cells(Rows.Count, 2).End(xlUp).Row
        For k = CurrRow To NewLastRow
            Sheets("Sheet2").Cells(k, 1).Value = Sheets("Sheet2").Cells(i, 19).Value
        Next k
        CurrRow = NewLastRow + 1

    Next i
HandlingIt:
    currErr = i
    For i = currErr + 1 To LastRow
        Set SapGuiAuto = GetObject("SAPGUI")  'Get the SAP GUI Scripting object
        Set SAPApp = SapGuiAuto.GetScriptingEngine 'Get the currently running SAP GUI
        Set SAPCon = SAPApp.Children(0) 'Get the first system that is currently connected
        Set session = SAPCon.Children(0) 'Get the first session (window) on that connection
        'Start the transaction to view a table
        session.StartTransaction "Transaction"

        session.findById("wnd[0]").maximize
        session.findById("wnd[0]/tbar[1]/btn[16]").press

        session.findById("wnd[0]/tbar[1]/btn[8]").press
        On Error GoTo HandlingIt
        session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").SelectAll
        session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").contextMenu
        session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").selectContextMenuItemByText "Copy Text"

        Workbooks("WorkbookName").Activate
        Sheets("Sheet2").Select
        Cells(CurrRow, 2).Select
        ActiveSheet.Paste
        NewLastRow = Sheets("Sheet2").Cells(Rows.Count, 2).End(xlUp).Row
        For k = CurrRow To NewLastRow
            Sheets("Sheet2").Cells(k, 1).Value = Sheets("Sheet2").Cells(i, 19).Value
        Next k
        CurrRow = NewLastRow + 1

    Next i
End If

一旦我已经处于On Error GoTo部分,是否有可能引用代码的另一个On Error GoTo部分?或者甚至返回到当前On Error GoTo部分的开头?

没有理由重复代码。如果您只是想在遇到错误时跳过循环的其余部分,那么您完全可以这样做

另一方面,当您完成错误处理时,应始终重置
OnError
行为(通过运行
OnError GoTo 0
)。您不希望代码中的bug进一步神秘地将您发送回循环。调试是噩梦中的事情

    For i = 2 To LastRow
        Set SapGuiAuto = GetObject("SAPGUI")  'Get the SAP GUI Scripting object
        Set SAPApp = SapGuiAuto.GetScriptingEngine 'Get the currently running SAP GUI
        Set SAPCon = SAPApp.Children(0) 'Get the first system that is currently connected
        Set session = SAPCon.Children(0) 'Get the first session (window) on that connection
        'Start the transaction to view a table
        session.StartTransaction "Transaction"

        session.findById("wnd[0]").maximize
        session.findById("wnd[0]/tbar[1]/btn[16]").press
        session.findById("wnd[0]/tbar[1]/btn[8]").press
        On Error GoTo NextLoopIteration
        session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").SelectAll
        session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").contextMenu
        session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").selectContextMenuItemByText "Copy Text"

        Workbooks("WorkbookName").Activate
        Sheets("Sheet2").Select
        Cells(CurrRow, 2).Select
        ActiveSheet.Paste
        NewLastRow = Sheets("Sheet2").Cells(Rows.Count, 2).End(xlUp).Row
        For k = CurrRow To NewLastRow
            Sheets("Sheet2").Cells(k, 1).Value = Sheets("Sheet2").Cells(i, 19).Value
        Next k
        CurrRow = NewLastRow + 1

NextLoopIteration:
        On Error GoTo 0
    Next i

未经测试,就这样做了

Function sapObjectExist (session as object) as boolean
   On error goto EH
   session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").SelectAll
   exit function
EH:
   sapObjectExist  = false
End Function
供进一步阅读


如果出现错误,您可以直接跳到下一个循环迭代,并在继续下一个迭代之前重置错误处理程序。请参阅代码中的注释

Sub SAPEverything()

    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    ans = MsgBox("Are you currently logged into SAP?", vbYesNoCancel)

    If ans = vbNo Then
        MsgBox ("Please log into SAP, then come back to this macro.")
        Exit Sub
    ElseIf ans = vbCancel Then
        Exit Sub
    ElseIf ans = vbYes Then
        frmSAP.Show
        frmSAP.Hide

        LastRow = Sheets("Sheet2").Cells(Rows.Count, 19).End(xlUp).Row
        CurrRow = 2

        For i = 2 To LastRow
            Set SapGuiAuto = GetObject("SAPGUI")  'Get the SAP GUI Scripting object
            Set SAPApp = SapGuiAuto.GetScriptingEngine 'Get the currently running SAP GUI
            Set SAPCon = SAPApp.Children(0) 'Get the first system that is currently connected
            Set session = SAPCon.Children(0) 'Get the first session (window) on that connection
            'Start the transaction to view a table
            session.StartTransaction "Transaction"

            session.findById("wnd[0]").maximize
            session.findById("wnd[0]/tbar[1]/btn[16]").press
            session.findById("wnd[0]/tbar[1]/btn[8]").press

            ' Enable error handler, in case of any error, execution will go to SkipIt.
            On Error GoTo SkipIt

            session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").SelectAll
            session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").contextMenu
            session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").selectContextMenuItemByText "Copy Text"

            Workbooks("WorkbookName").Activate
            Sheets("Sheet2").Select
            Cells(CurrRow, 2).Select
            ActiveSheet.Paste
            NewLastRow = Sheets("Sheet2").Cells(Rows.Count, 2).End(xlUp).Row
            For k = CurrRow To NewLastRow
                Sheets("Sheet2").Cells(k, 1).Value = Sheets("Sheet2").Cells(i, 19).Value
            Next k

            CurrRow = NewLastRow + 1

SkipIt:
            On Error GoTo 0 ' Reset error handler.

        Next i

    End If
End Sub

将错误处理代码与“快乐路径”完全分开。您希望错误处理子例程中的代码仅在出现运行时错误时执行,最重要的是您希望处理该错误-为此使用
Resume[label]
指令

Public Sub DoSomething()
    'do stuff...
    On Error GoTo CleanFail
    For i = a To b
       'do more stuff...
Skip:
    Next
    Exit Sub ' end of happy path

CleanFail: ' begin error handling code
    Debug.Print Err.Description; ". Skipping iteration #" & i
    Resume Skip ' clears error state and jumps to Skip label
End Sub

如果您发现自己需要不止一个错误处理子例程,那么您的过程做的事情太多了。把它分解成更小的过程,做更少的事情,因此失败的原因更少。

我有点困惑;如果你在一行中遇到错误,你只是想跳过该行的其余代码吗?@JoshEller是的,这就是我要做的。我想转到新行(下一个表名),您应该事先检查表是否存在。顺便说一句,正如您没有提到的,我们谈论的是什么类型的表,“普通”gui表控件还是alv网格?@Storax在代码中,还是在运行宏之前?如果是前者,我会怎么做?我不熟悉连接SAP和Excel。我相信这是一个alv网格。用sapsession作为变量编写一个函数谢谢你的回答。然而,我把它放在vba中并运行它,它只是一直停留在第一行(第一个表名)。它找不到“next i”语句,因为它位于错误处理程序中。关于如何解决这个问题有什么建议吗?@abbsichel在第一次迭代之后,错误处理会被重置,因为“错误处理程序”与“快乐路径”交织在一起,所以每次迭代都会运行
on error GoTo 0
,这会否定此循环之前的任何
on error GoTo NextLoopIteration
语句。解决方案是将错误处理代码与过程逻辑分离,并确保错误处理子例程中的代码仅在VBA处于错误状态时执行。或者就像另一个答案一样,在循环体中牛仔它并坚持错误转到下一个循环迭代/
skipit