I've got a problem with a VBA SAP script. I have data in excel and I want to execute the transaction code IW41 by copying and pasting data from Excel. I have all of the data like dates, number of orders, who did it etc in Excel and I want to automate it. I did a loop for variable i but I get an error and I cannot fix it.
Error :
Run-time error '619': Application-defined or object-defined error
Code provided below.
Can you give me some pro tips or help me fix it?
Screen in IW41 where the error occurs:
Code :
Sub ConfirmPM_Nots()
SystemName = "CCP" 'change as needed or use a variable
Transaction = "SESSION_MANAGER" 'change as needed or use a variable
On Error GoTo ErrorHandler:
If Not IsObject(Sap_Applic) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set Sap_Applic = SapGuiAuto.GetScriptingEngine
End If
On Error GoTo 0
koniec:
qConnections = Sap_Applic.Connections.Count
If qConnections = 0 Then
MsgBox "No connection to SAP"
End
End If
bSession = False
For iConnectionCounter = 0 To qConnections - 1
Set Connection = Sap_Applic.Children(Int(iConnectionCounter))
If Not Connection.Description = "" Then
qSessions = Connection.Children.Count
For iSessionCounter = 0 To qSessions - 1
Set session = Connection.Children(Int(iSessionCounter))
If session.info.SystemName <> SystemName Then Exit For
If session.info.Transaction = Transaction Then
bSession = True
Exit For
End If
Next
End If
If bSession Then Exit For
Next
If Not bSession Then
MsgBox SystemName & " not available or free session not available"
End
End If
Do
i = 1
session.findById("wnd[0]").resizeWorkingPane 128, 37, False
session.findById("wnd[0]/tbar[0]/okcd").Text = "iw41"
session.findById("wnd[0]").sendVKey 0
Order = Cells(i, 1)
b = Cells(i, 2)
c = Cells(i, 3)
d = Cells(i, 4)
session.findById("wnd[0]/usr/ctxtCORUF-AUFNR").Text = Order
session.findById("wnd[0]/usr/ctxtCORUF-AUFNR").caretPosition = 7
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/usr/tblSAPLCORUTC_3100/txtAFVGD-VORNR[1,0]").SetFocus
session.findById("wnd[0]/usr/tblSAPLCORUTC_3100/txtAFVGD-VORNR[1,0]").caretPosition = 2
session.findById("wnd[0]").sendVKey 2
session.findById("wnd[0]/usr/chkAFRUD-AUERU").Selected = True
session.findById("wnd[0]/usr/chkAFRUD-LEKNW").Selected = True
session.findById("wnd[0]/usr/ctxtAFRUD-ISDD").Text = c
session.findById("wnd[0]/usr/txtAFRUD-IDAUR").Text = b
session.findById("wnd[0]/usr/ctxtAFRUD-IEDD").Text = c
session.findById("wnd[0]/usr/txtAFRUD-LTXA1").Text = d
session.findById("wnd[0]/usr/txtAFRUD-LTXA1").SetFocus
session.findById("wnd[0]/usr/txtAFRUD-LTXA1").caretPosition = 10
session.findById("wnd[0]/tbar[0]/btn[11]").press
i = i + 1
Loop
Exit Sub
ErrorHandler:
MsgBox "No connection to SAP"
End
End Sub
"iw41" (from session.findById("wnd[0]/tbar[0]/okcd").Text = "iw41") only works if the current screen is the start menu. OK-Code "/niw41" will always work! So this code might work (untested):
Do
i = 1
' session.findById("wnd[0]").resizeWorkingPane 128, 37, False
' iw41 only works in the start menu. OK-Code /niw41 will always work!
session.findById("wnd[0]/tbar[0]/okcd").Text = "/niw41"
session.findById("wnd[0]").sendVKey 0
Order = Cells(i, 1)
b = Cells(i, 2).value
c = Cells(i, 3).value
d = Cells(i, 4).value
session.findById("wnd[0]/usr/ctxtCORUF-AUFNR").Text = Order
' session.findById("wnd[0]/usr/ctxtCORUF-AUFNR").caretPosition = 7
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/usr/tblSAPLCORUTC_3100/txtAFVGD-VORNR[1,0]").SetFocus
' session.findById("wnd[0]/usr/tblSAPLCORUTC_3100/txtAFVGD-VORNR[1,0]").caretPosition = 2
session.findById("wnd[0]").sendVKey 2
session.findById("wnd[0]/usr/chkAFRUD-AUERU").Selected = True
session.findById("wnd[0]/usr/chkAFRUD-LEKNW").Selected = True
session.findById("wnd[0]/usr/ctxtAFRUD-ISDD").Text = c
session.findById("wnd[0]/usr/txtAFRUD-IDAUR").Text = b
session.findById("wnd[0]/usr/ctxtAFRUD-IEDD").Text = c
session.findById("wnd[0]/usr/txtAFRUD-LTXA1").Text = d
' session.findById("wnd[0]/usr/txtAFRUD-LTXA1").SetFocus
' session.findById("wnd[0]/usr/txtAFRUD-LTXA1").caretPosition = 10
session.findById("wnd[0]/tbar[0]/btn[11]").press
i = i + 1
Loop
I also commented the lines with resizeWorkingPane, caretPosition and SetFocus because this is usually not needed. resizeWorkingPane will resize the SAPGUI screen and caretPosition is the position of a cursor within a textbox. Sometimes needed if you want to replace text for example. But in this case certainly not.
NOTE: Your need to exit our Do Loop and place the record pointer i out of the loop. Otherwise i = 1. To exit the loop I often use first blank cell value.
This way you can set the first record to start with, and in most cases i=2 as most sheets have used first row as headers.
i = 1
Do Until Cells(i, 1) = ""
' code
i = i + 1
Loop
When I debugged the code to use it in my own update of Equipment in SAP, I found that our SAP does not have Connection.Description so I just pick up the first session like this.
This worked just fine for me:
Sub SetEQLocations()
' Script written by Svein Aren Hylland 02.12.2022
' Use of VBScript recording from SAP to work with SAP transaction IE02 - Change Equipment.
' The sub will transfere new Location data found in sheet on all visible rows with filter and headers in first row.
' Code will show progress in first column while it updates each EQ in SAP.
'
Sv = MsgBox("This routine work towards SAP IE02 from row 2 - and will update all EQ locations as shown in this sheet.", vbOKCancel)
If Sv = vbCancel Then Exit Sub
SystemName = "KO3" 'change as needed or use a variable
Transaction = "SESSION_MANAGER" 'change as needed or use a variable
On Error GoTo ErrorHandler:
If Not IsObject(Sap_Applic) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set Sap_Applic = SapGuiAuto.GetScriptingEngine
End If
On Error GoTo 0
koniec:
qConnections = Sap_Applic.Connections.Count
If qConnections = 0 Then
MsgBox "No connection to SAP"
End
End If
'MsgBox Sap_Applic.Children(0).info.SystemName
bSession = False
For iConnectionCounter = 0 To qConnections - 1
Set Connection = Sap_Applic.Children(Int(iConnectionCounter))
'MsgBox Connection.Description
'If Not Connection.Description = "" Then
qSessions = Connection.Children.Count
For iSessionCounter = 0 To qSessions - 1
Set Session = Connection.Children(Int(iSessionCounter))
'MsgBox Session.info.SystemName
If Session.info.SystemName <> SystemName Then Exit For
If Session.info.Transaction = Transaction Then
bSession = True
Exit For
End If
Next
'End If
If bSession Then Exit For
Next
If Not bSession Then
MsgBox SystemName & " not available or free session not available"
End
End If
'Stop
Session.findById("wnd[0]").resizeWorkingPane 154, 24, False
Session.findById("wnd[0]/tbar[0]/okcd").Text = "ie02"
Session.findById("wnd[0]").sendVKey 0
i = 2
Do Until Cells(i, 1) = ""
If Cells(i, 1).Rows.Hidden = False Then
EQ = Cells(i, 1)
' Display progress
Cells(i, 1).Select
Cells(i, 1).Interior.Color = vbYellow
' Get data from sheet to be poulated in SAP fields
CostCenter = Cells(i, 14) ' Organization/Cost Center
MainWC = Cells(i, 15) ' Organization/Main Work Center
LocWorkCenter = Cells(i, 16) ' Location/Work Center
LocRoom = Cells(i, 17) ' Location/Room
Session.findById("wnd[0]/usr/ctxtRM63E-EQUNR").Text = EQ
Session.findById("wnd[0]/tbar[0]/btn[0]").press
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\02").Select
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\02/ssubSUB_DATA:SAPLITO0:0102/subSUB_0102A:SAPLITO0:1050/txtITOB-MSGRP").Text = LocRoom
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\02/ssubSUB_DATA:SAPLITO0:0102/subSUB_0102A:SAPLITO0:1050/txtITOB-MSGRP").SetFocus
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\02/ssubSUB_DATA:SAPLITO0:0102/subSUB_0102A:SAPLITO0:1050/txtITOB-MSGRP").caretPosition = 6
Session.findById("wnd[0]").sendVKey 0
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\02/ssubSUB_DATA:SAPLITO0:0102/subSUB_0102A:SAPLITO0:1050/ctxtITOBATTR-ARBPL").Text = LocWorkCenter
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\02/ssubSUB_DATA:SAPLITO0:0102/subSUB_0102A:SAPLITO0:1050/ctxtITOBATTR-ARBPL").SetFocus
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\02/ssubSUB_DATA:SAPLITO0:0102/subSUB_0102A:SAPLITO0:1050/ctxtITOBATTR-ARBPL").caretPosition = 6
Session.findById("wnd[0]").sendVKey 0
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\03").Select
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\03/ssubSUB_DATA:SAPLITO0:0102/subSUB_0102A:SAPLITO0:1052/ctxtITOB-KOSTL").Text = CostCenter
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\03/ssubSUB_DATA:SAPLITO0:0102/subSUB_0102B:SAPLITO0:1062/ctxtITOBATTR-GEWRK").Text = MainWC
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\03/ssubSUB_DATA:SAPLITO0:0102/subSUB_0102B:SAPLITO0:1062/ctxtITOBATTR-GEWRK").SetFocus
Session.findById("wnd[0]/usr/tabsTABSTRIP/tabpT\03/ssubSUB_DATA:SAPLITO0:0102/subSUB_0102B:SAPLITO0:1062/ctxtITOBATTR-GEWRK").caretPosition = 6
Session.findById("wnd[0]").sendVKey 0
Session.findById("wnd[0]/tbar[0]/btn[11]").press
End If
i = i + 1
Loop
Exit Sub
ErrorHandler:
MsgBox "No connection to SAP"
End
End Sub
Related
I have a form with two different listboxes. One for downtime data and one for production data. I can add new data and delete data via both listboxes. I can edit a selected row as well. The problem I'm running into is that after I edit and update a row for the production listbox and then enter in new data for new row it keeps putting that data in the last row I edited. If I don't edit a row then anytime I add new data it automatically goes to the next row. This doesn't happen with the downtime section, only the production section. With the downtime section everything works as it should. Attached is the workbook. Any help is greatly appreciated.
This is the code to update the listbox with what was entered into the text boxes above the listbox.
Sub Prod_Submit()
Dim sh As Worksheet
Dim iRow As Long
Set sh = ThisWorkbook.Sheets("ADHData")
If MainForm.txtRowNumberProd.Value = "" Then
iRow = [Counta(ADHData!A:A)] + 1
Else
iRow = MainForm.txtRowNumberProd.Value
End If
With sh
.Cells(iRow, 1) = MainForm.OrderA.Value
.Cells(iRow, 2) = MainForm.StockA.Value
.Cells(iRow, 3) = MainForm.FaceA.Value
.Cells(iRow, 4) = MainForm.LinerA.Value
.Cells(iRow, 5) = MainForm.WidthA.Value
.Cells(iRow, 6) = MainForm.PrevContA.Value
.Cells(iRow, 7) = MainForm.ContA.Value
.Cells(iRow, 8) = MainForm.PrevGoodA.Value
.Cells(iRow, 9) = MainForm.GoodA.Value
End With
End Sub
This is my code for selecting the row that needs to be edited
Private Sub CommandButton2_Click()
If Select_Prod = 0 Then
MsgBox "No row is selected.", vbOKOnly + vbInformation, "Edit"
Exit Sub
End If
MainForm.txtRowNumberProd.Value = Select_Prod + 1
MainForm.OrderA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 0)
MainForm.StockA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 1)
MainForm.FaceA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 2)
MainForm.LinerA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 3)
MainForm.WidthA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 4)
MainForm.PrevContA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 5)
MainForm.ContA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 6)
MainForm.PrevGoodA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 7)
MainForm.GoodA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 8)
MsgBox "Please make the required changes and update the new production data.", vbOKOnly + vbInformation, "Edit"
End Sub
And this is my Select_Prod Code
Function Select_Prod() As Long
Dim i As Long
Select_Prod = 0
For i = 0 To MainForm.Production_TableA.ListCount - 1
If MainForm.Production_TableA.Selected(i) = True Then
Select_Prod = i + 1
Exit For
End If
Next i
End Function
And my code to reset the textboxes
Sub Prod_Reset()
Dim iRow As Long
iRow = [Counta(ADHData!A:A)] + 1 ' idetifying the last row
With MainForm
MainForm.OrderA.Value = ""
MainForm.StockA.Value = ""
MainForm.FaceA.Value = ""
MainForm.LinerA.Value = ""
MainForm.WidthA.Value = ""
MainForm.PrevContA.Value = ""
MainForm.ContA.Value = ""
MainForm.PrevGoodA.Value = ""
MainForm.GoodA.Value = ""
.Production_TableA.ColumnCount = 9
.Production_TableA.ColumnHeads = True
.Production_TableA.ColumnWidths = "55,55,70,71,50,106,77,69,42"
If iRow > 1 Then
.Production_TableA.RowSource = "ADHData!A2:J" & iRow
Else
.Production_TableA.RowSource = "ADHData!A2:J21"
End If
End With
End Sub
I have a column in excel with values and I would like that when the code run through all the cells it starts again, at the cell A2.
The code works smooth, I'm only having trouble to keep the loop going on.
Sub Loopall()
i = 2
Do While Cells(i, 1) <> ""
Range("A2").Select
Session.FindById("wnd[0]").maximize
Session.FindById("wnd[0]/tbar[0]/okcd").Text = "fbl5n"
Session.FindById("wnd[0]").sendVKey 0
Session.FindById("wnd[0]/usr/ctxtDD_KUNNR-LOW").Text = Cells(i, 1)
Session.FindById("wnd[0]").sendVKey 8
Application.Wait (Now + TimeValue("0:00:02"))
Session.FindById("wnd[0]").sendVKey 3
i = i + 1
If Cells(i, 1) <> "" Then
i = 2
Else
End If
Loop
End sub
I've tried to place the if statement inside the loop, but then the code only reads the first cell. When placing the if outside the loop the code doesn't start the loop again when the cells are empty.
If Cells(i, 1) <> "" Then is restarting your loop when the cell is not blank, which seems like the opposite of what you'd want?
Sub Loopall()
Const START_ROW as Long = 2
i = START_ROW
Do
Session.FindById("wnd[0]").maximize
Session.FindById("wnd[0]/tbar[0]/okcd").Text = "fbl5n"
Session.FindById("wnd[0]").sendVKey 0
Session.FindById("wnd[0]/usr/ctxtDD_KUNNR-LOW").Text = Cells(i, 1)
Session.FindById("wnd[0]").sendVKey 8
Application.Wait (Now + TimeValue("0:00:02"))
Session.FindById("wnd[0]").sendVKey 3
i = i + 1
If Len(Cells(i, 1)) = 0 Then i = START_ROW
Loop
End sub
Probably want to add in some way to escape the loop...
I'm able to unblock the outlets by utilizing a SAP GUI script and VBA macros. I need to keep the outlet code(Column a) and status 0(Column B) on an Excel sheet, and then when I click start script, sap will perform the unblocking activities.
Excel template looks as follows,
This VBA code works.
Option Explicit
Public SapGuiAuto, WScript, msgcol
Public objGui As GuiApplication
Public objConn As GuiConnection
Public objSess As GuiSession
Public objSBar As GuiStatusbar
Public objSheet As Worksheet
Dim W_System
Dim iCtr As Integer
Const tcode = "XD05"
Function Attach_Session(iRow, Optional mysystem As String) As Boolean
Dim il, it
Dim W_conn, W_Sess
' Unless a system is provided (XXXYYY where XXX is SID and YYY client)
' get the system from the sheet (in this case it is in cell A8)
If mysystem = "" Then
W_System = ActiveSheet.Cells(iRow, 1)
Else
W_System = mysystem
End If
' If we are already connected to a session, exit do not try again
If W_System = "" Then
Attach_Session = False
Exit Function
End If
' If the session object is not nil, use that session (assume connected to the correct session)
If Not objSess Is Nothing Then
If objSess.Info.SystemName & objSess.Info.Client = W_System Then
Attach_Session = True
Exit Function
End If
End If
' If not connected to anything, set up the objects
If objGui Is Nothing Then
Set SapGuiAuto = GetObject("SAPGUI")
Set objGui = SapGuiAuto.GetScriptingEngine
End If
' Cycle through the open SAP GUI sessions and check which is in the same system running the matching transaction
For il = 0 To objGui.Children.Count - 1
Set W_conn = objGui.Children(il + 0)
For it = 0 To W_conn.Children.Count - 1
Set W_Sess = W_conn.Children(it + 0)
If W_Sess.Info.SystemName & W_Sess.Info.Client = W_System Then
Set objConn = objGui.Children(il + 0)
Set objSess = objConn.Children(it + 0)
Exit For
End If
Next
Next
' If nothing is found, display and error message
If objSess Is Nothing Then
MsgBox "No active session to system " + W_System + " with transaction " + tcode + ", or scripting is not enabled.", vbCritical + vbOKOnly
Attach_Session = False
Exit Function
End If
' Turn on scripting
If IsObject(WScript) Then
WScript.ConnectObject objSess, "on"
WScript.ConnectObject objGui, "on"
End If
' Maximize the window of the connected session
Set objSBar = objSess.findById("wnd[0]/sbar")
objSess.findById("wnd[0]").Iconify
Attach_Session = True
End Function
Public Sub StartProcessing()
Dim W_Obj1, W_Obj2, W_Obj3, W_Obj4, iRow
Dim W_Func
Dim W_Src_Ord
Dim W_Ret As Boolean
Dim itemcount As Integer
Dim itemmax As Integer
Const startrow As Integer = 5 'First row with actual data
Set objSheet = ActiveWorkbook.ActiveSheet
' Connect to a system stored in cell A8
W_Ret = Attach_Session(2)
If Not W_Ret Then
MsgBox "Not connected to client"
GoTo MyEnd
End If
itemcount = 0
itemmax = 0
' Determine the number of items to be processed: where the status is zero
For iRow = startrow To objSheet.UsedRange.Rows.Count
If objSheet.Cells(iRow, 2) = "0" Then
itemmax = itemmax + 1
End If
Next
' Update the counter in cell A9
objSheet.Cells(3, 1) = itemcount & "/" & itemmax
' Cycle through the rows with status 0 and call the ProcessRow function to process them
For iRow = startrow To objSheet.UsedRange.Rows.Count
If objSheet.Cells(iRow, 2) = "0" Then
Call ProcessRow(iRow)
itemcount = itemcount + 1
objSheet.Cells(3, 1) = itemcount & "/" & itemmax
End If
Next
MyEnd:
' destory the objects, free up memory
Set objSess = Nothing
Set objGui = Nothing
Set SapGuiAuto = Nothing
MsgBox "Script completed.", vbInformation + vbOKOnly
End Sub
Function ProcessRow(iRow)
Dim W_BPNumber, W_Blockcode, W_Companycode, W_Salesorg
Dim lineitems As Long
' Set the line status to "processing..."
objSheet.Cells(iRow, 2) = 1
'BP Number
If objSheet.Cells(iRow, 1) <> "" Then
W_BPNumber = objSheet.Cells(iRow, 1)
Else
W_BPNumber = "xxxxxx"
End If
'Company Code
If objSheet.Cells(iRow, 2) <> "03" Then
W_Companycode = objSheet.Cells(iRow, 2)
Else
W_Companycode = "xxxxxx"
End If
'Sales Org
If objSheet.Cells(iRow, 4) <> "" Then
W_Salesorg = objSheet.Cells(iRow, 4)
Else
W_Salesorg = "xxxxxx"
End If
'Block Code
If objSheet.Cells(iRow, 5) <> "" Then
W_Blockcode = objSheet.Cells(iRow, 5)
Else
W_Blockcode = ""
End If
' Set error handling to the below code where we can capture if a line had failed in the GUI script
On Error GoTo myerr
' SAP GUI Script starts here
objSess.findById("wnd[0]").Iconify
'objSess.findById("wnd[0]").Maximize
objSess.findById("wnd[0]/tbar[0]/okcd").Text = "/nXD05"
objSess.findById("wnd[0]").sendVKey 0
objSess.findById("wnd[0]/usr/ctxtRF02D-KUNNR").Text = W_BPNumber
objSess.findById("wnd[0]/usr/ctxtRF02D-BUKRS").Text = "1172"
objSess.findById("wnd[0]/usr/ctxtRF02D-VKORG").Text = "1172"
objSess.findById("wnd[0]/usr/ctxtRF02D-VTWEG").Text = "10"
objSess.findById("wnd[0]/usr/ctxtRF02D-SPART").Text = "00"
objSess.findById("wnd[0]/usr/ctxtRF02D-SPART").SetFocus
objSess.findById("wnd[0]/usr/ctxtRF02D-SPART").caretPosition = 2
objSess.findById("wnd[0]").sendVKey 0
objSess.findById("wnd[0]/usr/ctxtKNA1-AUFSD").Text = ""
objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").Text = ""
objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").SetFocus
objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").caretPosition = 0
objSess.findById("wnd[0]/tbar[0]/btn[11]").press
objSess.findById("wnd[0]").sendVKey 12
' Gets the message from the status bar and save it in column B
objSheet.Cells(iRow, 5) = objSBar.Text
' Update the Status to "Completed" and exit
objSheet.Cells(iRow, 2) = 2
Exit Function
myerr:
' Update the status to "Error"
objSheet.Cells(iRow, 2) = 3
End Function
My requirements
If the following field in sap has the value 03, the outlet should be unblocked; otherwise, an error message should show in the excel file for that particular outlet.
objSess.findById("wnd[0]/usr/ctxtKNA1-AUFSD").Text = ""
objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").Text = ""
How to achieve this with VBA?
not sure I fully understand what you are asking here but maybe something like this:
Const cBlockText As String = "03"
objSess.findById("wnd[0]").Iconify
objSess.findById("wnd[0]/tbar[0]/okcd").Text = "/nXD05"
objSess.findById("wnd[0]").sendVKey 0
objSess.findById("wnd[0]/usr/ctxtRF02D-KUNNR").Text = W_BPNumber
objSess.findById("wnd[0]/usr/ctxtRF02D-BUKRS").Text = "1172"
objSess.findById("wnd[0]/usr/ctxtRF02D-VKORG").Text = "1172"
objSess.findById("wnd[0]/usr/ctxtRF02D-VTWEG").Text = "10"
objSess.findById("wnd[0]/usr/ctxtRF02D-SPART").Text = "00"
objSess.findById("wnd[0]").sendVKey 0
' New code here:
' Not sure of and/or rules?
If objSess.findById("wnd[0]/usr/ctxtKNA1-AUFSD").Text = cBlockText _
Or objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").Text = cBlockText Then
objSheet.Cells(iRow, 5) = "Unable to block: Dispute with customer"
objSess.findById("wnd[0]/tbar[0]/okcd").Text = "/n"
objSess.findById("wnd[0]").sendVKey 0
Else
objSess.findById("wnd[0]/usr/ctxtKNA1-AUFSD").Text = ""
objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").Text = ""
objSess.findById("wnd[0]/tbar[0]/btn[11]").press
objSess.findById("wnd[0]").sendVKey 12
objSheet.Cells(iRow, 5) = objSBar.Text
' Update the Status to "Completed" and exit
objSheet.Cells(iRow, 2) = 2
End If
I'm working on a script that pings computers from a list periodically and returns information.
My problem is, whenever the the script is running, it steals focus from other excel windows.
For example if if I'm typing in another workbook when the scrip runs, it jumps (to the cell that was last selected) and continues writing in the cell.
Here is the script:
Sub autoping_cb()
Dim c As Range
Dim thePing As Variant
Dim TryCount As Integer
Dim TryAgainCount As Integer
Dim TryNextRun As Boolean
TryNextRun = False
Set sht = Application.ThisWorkbook.Worksheets(1)
LastRow = sht.Cells(sht.Rows.Count, "B").End(xlUp).Row
Dim chb As Shape
Set chb = ThisWorkbook.Worksheets(1).Shapes("autoping")
If chb.ControlFormat.Value = xlOn Then
sht.Range("H3").Value = Replace(sht.Range("H3").Value, ",", ".")
TryCount = 1
If sht.Range("H4") <> "" And IsNumeric(sht.Range("H4")) = True And sht.Range("H4") = Int(sht.Range("H4")) And sht.Range("H3") <> "" And IsNumeric(sht.Range("H3")) = True Then
TryAgainCount = sht.Range("H4").Value
If TryAgainCount = 0 Then
TryNextRun = True
End If
Do Until chb.ControlFormat.Value = xlOff
Wait ThisWorkbook.Worksheets(1).Range("H3").Value * 60 '<-- replace to 60 after testing
For Each c In Application.Worksheets(1).Range("B3:B" & LastRow)
If chb.ControlFormat.Value = xlOff Then
End
ElseIf chb.ControlFormat.Value = xlOn Then
If ispcname(c.Value) = True Or isip(c.Value) = True Then
If c.Offset(0, 2) = "--->" And TryNextRun = False Then
Else
c.Offset(0, 1) = nslookup(c.Value)
thePing = sPing(c.Value)
c.Offset(0, 2) = thePing(0)
c.Offset(0, 3) = GetErrorCode(thePing(1))
If c.Offset(0, 2).Value = "--->" Then
sht.Range("B" & c.Row & ":E" & c.Row).Style = "Bad"
ElseIf c.Offset(0, 2).Value < 50 Then
sht.Range("B" & c.Row & ":E" & c.Row).Style = "Good"
Else
sht.Range("B" & c.Row & ":E" & c.Row).Style = "Neutral"
End If
End If
End If
End If
sht.Range("B2:E" & LastRow + 1).Columns.AutoFit
Next c
If TryNextRun = False And TryCount < TryAgainCount Then
TryCount = TryCount + 1
Debug.Print 1
ElseIf TryNextRun = False And TryCount >= TryAgainCount Then
TryNextRun = True
TryCount = 1
Debug.Print 2
ElseIf TryNextRun = True And TryAgainCount <> 0 Then
TryNextRun = False
Debug.Print 3
End If
Loop
Else
MsgBox "invalid 'Ping every'/'try offline after' integer"
End If
End If
End Sub
It's a bit messy I know :-)
Beacuse all excel sheets are running on one thread (one Excel.exe instance, you can see one presence in task manager).
If you are running more excel instance, your sheet are working independently.
You can do one of these possibilities :
-simple open new Excel.exe from start menu, icon, etc
-windows tray excel icon right click then alt+click on Microsoft Excel
-start command (or shortcut or batch file): Excel.exe "xls path" /x
-vba
Sub OpenNewExcelInstance()
Dim xlApp As Excel.Application
Set xlApp = New Excel.Application
xlApp.Workbooks.Add
xlApp.Visible = True
Set xlApp = Nothing
End Sub
-modify your registry to force open in new instance
-modify your Personal.xlsb
i think the easiest solution is to use the task -scheduler, and start your macro from there. In the extend properties choose "run whether user is logged on or not", then this is started in a separate task.
I have created an Excel spreadsheet that extracts live data from a query in SAP GUI and paste that info back into Excel
From there, I'm opening transaction ME38 to update schedule lines based off the extracted data. I need to go to the "scheduled.." column (which I know to be "txtEKET-MENGE") and change the number shown to the "Qty Delivered" (which is a part of the extraction); however, I need to only do this on certain cells in the "Schedule..." column ("txtEKET-ETENR") [data listed on extraction as well].
When it gets to "Set grid..." it ends the function and does nothing else.
Any insight would be greatly appreciated.
Here is what I've done so far.
Set xclapp = CreateObject("Excel.Application")
Set xclwbk = ThisWorkbook
Set xclsht = xclwbk.Sheets("Sheet1")
For k = 2 To ActiveCell.SpecialCells(11).Row
For j = 1 To ActiveCell.SpecialCells(11).Column
If j = 14 Then Purch = xclsht.Cells(k, j).Value
If j = 15 Then Item = xclsht.Cells(k, j).Value
If j = 16 Then SLine = xclsht.Cells(k, j).Value
If j = 8 Then PGI = xclsht.Cells(k, j).Value
Next
myTransaction = "ME38"
Session.FindById("wnd[0]/tbar[0]/okcd").Text = "/n" & myTransaction
Session.FindById("wnd[0]").sendVKey 0
On Error Resume Next
Session.FindById("wnd[0]/usr/ctxtRM06E-EVRTN").Text = Purch
Session.FindById("wnd[0]/usr/ctxtRM06E-EVRTN").caretPosition = 10
Session.FindById("wnd[0]").sendVKey 0
Session.FindById("wnd[0]/usr/txtRM06E-EBELP").Text = Item
Session.FindById("wnd[0]/usr/txtRM06E-EBELP").caretPosition = 3
Session.FindById("wnd[0]").sendVKey 0
Session.FindById("wnd[0]/tbar[1]/btn[30]").press
Session.FindById("wnd[0]/tbar[1]/btn[2]").press
Call SelectRowOnGrid
Session.FindById("wnd[0]/mbar/menu[0]/menu[0]").Select
Session.FindById("wnd[0]").Close
On Error Resume Next
Session.FindById("wnd[1]/usr/btnSPOP-OPTION1").press
Next
End If
If Err.Number <> 0 Then
'The Excel worksheet has e.g. 3 columns of data and an error column.
xclsht.Cells(j, 21).Value = "Here is an error."
Else
xclsht.Cells(j, 21).Value = "O.K."
End If
On Error GoTo 0
The following is the Function SelectRowOnGrid.
Function SelectRowOnGrid()
Dim grid As SAPFEWSELib.GuiTableControl
Dim columnname As SAPFEWSELib.GuiTableColumn
Dim texttofind As String
Set grid = Session.FindById("wnd[0]/usr/tblSAPMM06ETC_1117/")
Set columnname = Session.FindById("wnd[0]/usr/tblSAPMM06ETC_1117/txtEKET- ETENR")
texttofind = xclsht.Cells(k, 16).Value
For k = 0 To grid.RowCount - 1
If grid.GetCellValue(k, columnname) = texttofind Then
grid.SetCurrentCell
grid.DoubleClickCurrentCell
End If
Next k
End Function
I will give you an example of how to deal with a table in SAP. In your case you use the commands for a GRID and this is not correct.
for example:
myFile = "z:\tmp\test.xlsx"
mySheet = "Test"
Set xclApp = CreateObject("Excel.Application")
Set xclwbk = xclapp.Workbooks.Open(myFile)
set xclsht = xclwbk.Sheets(mySheet)
xclApp.Visible = True
xclapp.DisplayAlerts = false
k = 1
do
set myTable = session.findById("wnd[0]/usr/ssubITEMS:SAPLFSKB:0100/tblSAPLFSKBTABLE")
if k = 1 then
'rows = myTable.RowCount
cols = myTable.Columns.Count
vRows = myTable.VisibleRowCount
for j = 0 to cols - 1
xclsht.Cells(k,j + 1).Value = myTable.columns.elementAt(j).title
next
k = k + 1
end if
for i = 0 to vRows - 1
l = 1
for j = 0 to Cols - 1
on error resume next
myVariable = trim(myTable.GetCell(i,j).Text)
if err.number <> 0 then exit for
on error goto 0
if left(right(myVariable,3),1) = "," then
myVariable = replace(myVariable, "." , "")
myVariable = replace(myVariable, "," , "")
xclsht.Cells(k,l).Value = myVariable/100
else
xclsht.Cells(k,l).Value = myVariable
end if
l = l + 1
next
if err.number <> 0 then exit for
k = k + 1
next
if err.number <> 0 then exit do
myTable.VerticalScrollbar.Position = myTable.VerticalScrollbar.Position + vRows
Loop
xclapp.ActiveWorkbook.Save
Set xclwbk = Nothing
Set xclsheet = Nothing
set xclapp = Nothing
Regards,
ScriptMan