Filling BAPI import table parameter in EXCEL using VBA - excel

I have a query for me which requires to clear. I am using excel 2003. the sheet contains 12 columns. I need to do export data from excel to SAP. Before exporting I need to check if the record is exist or not, if exist then delete and insert.
I have two BAPIs for this one is import table, which needs to be filled the parameters, after filling this table the BAPI searches for the relevant records.
The list will be displayed in a table. I need to search that table with values from excel then import one field value to excel.
I write this code but, it is not working the BAPI giving Error 0.
Public Function Import_Order() As Boolean
Dim oBAPIGetOrder As Object
Dim oBAPIVariant1 As Object
Dim oBAPIVariant2 As Object
Dim oBAPIVariant3 As Object
Dim oBAPIImpOrder As Variant
Dim oBAPIRet As Boolean
Dim oDoNothing As Variant
gBAPIPlanOrder = 0
Set oBAPIGetPlOrder = sBAPIControl.Add("PLANED_GET_DET_LIST") 'BAPI
Set oBAPIVariant1 = oBAPIGetPlOrder.exports.Item("SELECTIONCRITERIA") 'Internal table
Set oBAPIVariant2 = oBAPIGetPlOrder.Tables.Item("DETAILEDLIST") 'Table
oBAPIVariant1.Value("MATERIAL") = eMaterial
oBAPIVariant1.Value("PLANT") = ePlnPlant
lBAPIRet = oBAPIGetPlOrder.call
If lBAPIRet Then
'oBAPIImpOrder = oBAPIGetPlOrder.imports.Item("PLANNEDORDER_NUM")
a = oBAPIVariant2.Rows.Count
oBAPIImpOrder = oBAPIVariant2.Value("PLANNEDORDER_NUM")
Import_PlannedOrder = True
Else
oBAPIImpOrder = 0
Import_PlannedOrder = False
End If
End Function
Thanks in advance for any help...

please place the call function statement
lBAPIRet = oBAPIGetPlOrder.call
after directly the exports statement and before the tables and importstatements

Related

BAPI_MATERIAL_MRP_LIST returns empty values in VBA

I use an Excel macro to get values from SAP, especially for planned orders.
Function GetOrders(ByVal ProductNumber As String)
Dim OrderList As Object: Set OrderList = SAP.Add("BAPI_MATERIAL_MRP_LIST")
Dim OrderMat As Object: Set OrderMat = OrderList.Exports("MATERIAL")
Dim OrderPlant As Object: Set OrderPlant = OrderList.Exports("PLANT")
Dim OrderTable As Object: Set OrderTable = OrderList.Tables("MRP_IND_LINES")
OrderTable.FreeTable
OrderMat = ProductNumber
OrderPlant = "XXX"
OrderList.Call
Set GetOrders = OrderTable
Set OrderMat = Nothing
Set OrderPlant = Nothing
Set OrderTable = Nothing
End Function
I changed the OrderPlant for the question.
It's working on one PC but using the same SAP account on another one we get some empty values. Specifically all the numbers > 10k are not shown.
On my PC I get something like this as a result from the MRP_IND_LINES table:
P.cons 00XXXXXXXX/XXXXXX/XXXX -21.600.000
P.cons 00XXXXXXXX/XXXXXX/XXXX -3.600.000
On another PC I the -21.600.000 is empty so it shows like this:
P.cons 00XXXXXXXX/XXXXXX/XXXX
P.cons 00XXXXXXXX/XXXXXX/XXXX -3.600.000
The disappearing field is the "REC_REQD_QTY", number 16 of the table BAPI_MRP_IND_LINES (MRP: Single Lines of MRP Elements), Data Type: "QUAN"
The only difference between the PCs is the SAP logon GUI version, 720 on mine and 750 on the other PC.
This happens only on the big numbers. The other fields in the row are downloaded correctly.
I'm not using SAP GUI scripting, but I've created the SAP Object with the row
Set SAP = CreateObject("SAP.Functions.Unicode")

how to import excel to datagrid, then filter by db values

my question about import excel to datagridview but there is an extra case.
I have also a oledb database with store code and store names.
I want it to show only store codes from db that are in the database after imported.
my codes here;
Dim conn As OleDbConnection
Dim dtr As OleDbDataReader
Dim dta As OleDbDataAdapter
Dim cmd As OleDbCommand
Dim dts As DataSet
Dim excel As String
Dim OpenFileDialog As New OpenFileDialog
OpenFileDialog1.FileName = ""
OpenFileDialog1.InitialDirectory = My.Computer.FileSystem.SpecialDirectories.Desktop
OpenFileDialog1.Filter = "All Files (*.*)|*.*|Excel files (*.xlsx)|*.xlsx|CSV Files (*.csv)|*.csv|XLS Files (*.xls)|*xls"
If (OpenFileDialog1.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK) Then
DataGridView1.Columns.Clear()
Dim fi As New FileInfo(OpenFileDialog1.FileName)
Dim FileName As String = OpenFileDialog1.FileName
excel = fi.FullName
conn = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excel + ";Extended Properties=Excel 12.0;")
dta = New OleDbDataAdapter("Select * From [Sheet1$]", conn)
dts = New DataSet
dta.Fill(dts, "[Sheet1$]")
DataGridView1.DataSource = dts
DataGridView1.DataMember = "[Sheet1$]"
conn.Close()
End If
firstly sorry for my terrible english :)
images as follows;
Main Form
Store List Form
I want only the ones in the store list to be displayed in datagrid.. :\
It's not exactly clear what your current presentation/display looks like, what the problem is, and what your desired presentation/display should look like. But you have asked about selecting only one part of the data you are importing, which is presumably found in only one column of the imported Excel data.
When the datatable is created, it has the columns and rows from the Excel worksheet. The columns will be data from the first row, and the rows will be the records from the succeeding rows in the worksheet. You can access both the header data and the row data easily. The code below is VERY rough but for you to see how to gain access to the data in the datatable which you have already very successfully imported in the limited code shown above.
Dim columns = datatable.Columns
Dim rows = datatable.Rows
Dim columns1 = columns(0)
Dim rows1 = rows(0)
Dim element1 = rows1(0)
Columns will have all the headers, so you can locate the column with the store codes or store names. Then the rows will have the data for each store. So above, rows1 is the first row of data and element1 is the data in that row from columns1, and so on. The (0) is the index into the respective collections.
You will, of course, have to write code to extract the data you want and if necessary eliminate duplicates, but the data is all there already.
Hopefully getting the data into a list and then sorting, filtering and selecting the data should be relatively straightforward, but if not, add a comment. That's kind of a different problem. You asked about getting only the store codes.
Added: Based on your additional images and explanation, you are looking to perform an SQL INNER JOIN operation. From the w3schools.com page on SQL INNER JOIN, "The INNER JOIN keyword selects all rows from both tables as long as there is a match between the columns." This is something you will have to study and learn, but it should provide what you need in this case. You will need to define and construct both tables and then perform the JOIN.
And, by the way, you could also follow the link provided in the first comment by T.S., and if that solves your problem, it's a far simpler solution.

Selecting multiple fields in win32c.xlPageField

Objective: I'm using a python script to generate an excel report (contains lots of pivot tables).
Problem: Unable to figure out how to add multiple items to pivot table filter
I've figured out a cumbersome solution where I can create individual data sets that are pre-filtered so I don't need to filter them in the pivot table. However, this isn't really efficient or effective if somebody wants to swap the filter on the final excel report.
I'll use code I found online as an example:
import win32com.client
Excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
win32c = win32com.client.constants
wb = Excel.Workbooks.Add()
Sheet1 = wb.Worksheets("Sheet1")
TestData = [['Country','Name','Gender','Sign','Amount'],
['CH','Max' ,'M','Plus',123.4567],
['FR','Max' ,'M','Minus',-23.4567],
['CH','Max' ,'M','Plus',12.2314],
['SP','Max' ,'M','Minus',-2.2314],
['CH','Sam' ,'M','Plus',453.7685],
['CH','Sam' ,'M','Minus',-53.7685],
['CH','Sara','F','Plus',777.666],
['CH','Sara','F','Minus',-77.666],
['DE','Hans','M','Plus',345.088],
['DE','Hans','M','Minus',-45.088],
['DE','Paul','M','Plus',222.455],
['DE','Paul','M','Minus',-22.455]]
for i, TestDataRow in enumerate(TestData):
for j, TestDataItem in enumerate(TestDataRow):
Sheet1.Cells(i+2,j+4).Value = TestDataItem
cl1 = Sheet1.Cells(2,4)
cl2 = Sheet1.Cells(2+len(TestData)-1,4+len(TestData[0])-1)
PivotSourceRange = Sheet1.Range(cl1,cl2)
PivotSourceRange.Select()
wb.Worksheets.Add()
Sheet2 = wb.Worksheets("Sheet2")
cl3=Sheet2.Cells(4,1)
PivotTargetRange= Sheet2.Range(cl3,cl3)
PivotTableName = 'ReportPivotTable'
PivotCache = wb.PivotCaches().Create(SourceType=win32c.xlDatabase, SourceData=PivotSourceRange, Version=win32c.xlPivotTableVersion14)
PivotTable = PivotCache.CreatePivotTable(TableDestination=PivotTargetRange, TableName=PivotTableName, DefaultVersion=win32c.xlPivotTableVersion14)
PivotTable.PivotFields('Name').Orientation = win32c.xlRowField
PivotTable.PivotFields('Country').Orientation = win32c.xlPageField
PivotTable.PivotFields('Country').CurrentPage = 'SP'
PivotTable.PivotFields('Gender').Orientation = win32c.xlColumnField
PivotTable.PivotFields('Sign').Orientation = win32c.xlColumnField
DataField = PivotTable.AddDataField(PivotTable.PivotFields('Amount'))
Excel.Visible = 1
wb.SaveAs('ranges_and_offsets.xlsx')
Excel.Application.Quit()
This generates a pivot table in excel and sets the Country Filter to SP. I know adding the following line will enable the multi selection option.
PivotTable.PivotFields('Country').EnableMultiplePageItems = True
At this point, I'm stuck. I would like to find a way to set Country to both SP and DE. I feel like the correct way to do this is to switch .CurrentPage to .CurrentPageList
However, I can't seem to get .CurrentPageList to work
Any help would be highly appreciated!
this maybe too late for this post, but the way I solved this was creating two loops
PivotTable.PivotFields(target_column).Position = some_position
PivotTable.PivotFields(target_column).EnableMultiplePageItems = True
for item in show_values:
PivotTable.PivotFields(target_column).PivotItems(item).Visible = True
for item in excl_values:
PivotTable.PivotFields(target_column).PivotItems(item).Visible = False
I hope it helps!

VBA Customize collection object

I've been trying to learn how to create customized collections in Excel VBA and I found this piece of code on MSDN. While I understand most of it, can anyone tell me what the last code Set Add = empNew is doing? I don't understand it's comment. Thank you!
' Methods of the Employees collection class.
Public Function Add(ByVal Name As String, _
ByVal Salary As Double) As Employee
Dim empNew As New Employee
Static intEmpNum As Integer
' Using With makes your code faster and more
' concise (.ID vs. empNew.ID).
With empNew
' Generate a unique ID for the new employee.
intEmpNum = intEmpNum + 1
.ID = "E" & Format$(intEmpNum, "00000")
.Name = Name
.Salary = Salary
' Add the Employee object reference to the
' collection, using the ID property as the key.
mcolEmployees.Add empNew, .ID
End With
' Return a reference to the new Employee.
Set Add = empNew
End Function
You will notice that Add is the name of the Function. By issuing Set Add = newEmp your code is declaring that the return value (or object, in this case) of the function, is the newly created employee object newEmp. This means that the function will pass the variable newEmp back to its caller.
Say that you had some procedure calling your function, you would be able to do this:
Sub listEmployees
Dim e As Employee
' Create a new employee, and assign the variable e to point to this object
Set e = Add("John", 1000) ' Notice that the only reason we use "add" here is because it is the name of the function you provided
' e is now an Employee object, after being created in the line above, meaning we can access whatever properties is defined for it. The function Add lists some properties, so we can use those as examples.
Debug.Print e.Name
Debug.Print e.Salary
Debug.Print e.ID
End Sub
First, you need to define the new Type you have created, so put the following code on top of your module:
Public Type Employee
id As String
Name As String
Salary As Long
End Type
Then, inside your Public Function Add , change to Dim empNew As Employee.
Not sure why you need the following line : mcolEmployees.Add empNew, .id ??
and the last line modify to Add = empNew.
Then, when I test this Function from the following Sub:
Sub testEmp()
Dim s As Employee
s = Add("Shai", 50000)
End Sub
I get for s in the immediate window the following values:
s.id = E00001
s.Name = "Shai"
s.Salary = 50000
I hope this is what you intended in your post.

Export SQL query results into a multi tabbed Excel spreadsheet

I want to write a set of 100 select queries in DB2 10.1 to return all rows in each table in the database and have the results exported to an excel spreadsheet with a new tab for each result set.
Is this possible and if so how can I do it?
At the moment the only way I can do this looks like to export each result set and then manually create the multi tabbed spreadsheet by copying each tab across.
Thanks
You can use EasyXLS API for Excel with scripting languages like VB Script.
The VBS code should be similar with this one:
'The class that exports result set to Excel file
Set xls = CreateObject("EasyXLS.ExcelDocument")
' The class used to format the cells
Dim xlsAutoFormat
set xlsAutoFormat = CreateObject("EasyXLS.ExcelAutoFormat")
xlsAutoFormat.InitAs(AUTOFORMAT_EASYXLS1)
For query = 1 To 100
' Add a new sheet
xls.easy_addWorksheet_2("Sheet" & query)
set xlsSheet = xls.easy_getSheetAt(query - 1)
' Create the record set object
Dim objResultSet
Set objResultSet = CreateObject("ADODB.Recordset")
objResultSet.Open queryString, objDBConnection
' Create the list that will store the values of the result set
Dim lstRows
Set lstRows = CreateObject("EasyXLS.Util.List")
' Add the header to the list
Dim lstHeaderRow
Set lstHeaderRow = CreateObject("EasyXLS.Util.List")
lstHeaderRow.addElement("Column 1")
lstHeaderRow.addElement("Column 2")
lstHeaderRow.addElement("Column 3")
lstRows.addElement(lstHeaderRow)
' Add the values from the database to the list
Do Until objResultSet.EOF = True
set RowList = CreateObject("EasyXLS.Util.List")
RowList.addElement("" & objResultSet("Column 1"))
RowList.addElement("" & objResultSet("Column 2"))
RowList.addElement("" & objResultSet("Column 3"))
lstRows.addElement(RowList)
' Move to the next record
objResultSet.MoveNext
Loop
xlsSheet.easy_insertList_2 lstRows, xlsAutoFormat
Next
' Export result sets to Excel file
xls.easy_WriteXLSFile("c:\Result sets.xls")
Check also this link about exporting lists of data to Excel.
If you will choose a non scripting language, the API has methods that insert data directly from the result set and the lists can be skiped. Check another sample here.

Resources