cancel
Showing results for 
Search instead for 
Did you mean: 

Example: How to binding CFL to a UDO in a customized System Form.

Former Member
0 Kudos

Hi all.

This thread is posted to share and document (like a How to)

Any question, correction,... is wellcome.

Object.
These example illustrates how to add new fields into a system form and obtain valid values from a CFL.
These tutorial is exampled by the+ form 150+

1.

The first step is to add for the table OITM the field to stores the customized information for a Item.

a.

Add the new field(s) for a desired form (in the example the 150)

Public Sub AddUserFields()
 Dim oUserFieldsMD As SAPbobsCOM.UserFieldsMD
 If Not UserFieldsExist("OITM", "XX_MODEL") Then
   oUserFieldsMD = _ oCompany.GetBusinessObject(BoObjectTypes.oUserFields)
   oUserFieldsMD.TableName = "OITM"
   oUserFieldsMD.Name = "XX_MODEL"
   oUserFieldsMD.Description = "Model "
   oUserFieldsMD.Type = BoFieldTypes.db_Alpha
   oUserFieldsMD.SubType = BoFldSubTypes.st_None
   oUserFieldsMD.EditSize = 20
   oUserFieldsMD.Mandatory = BoYesNoEnum.tNO
   oUserFields.Add(oUserFieldsMD)
   System.Runtime.InteropServices.Marshal.ReleaseComObject( oUserFieldsMD)
 End If
End Sub

Public Function UserFieldsExist(ByVal tableName As String, ByVal fieldName As String) As Boolean
 Dim oTmpRecordset As SAPbobsCOM.Recordset

 oTmpRecordset = _  CType(oCompany.GetBusinessObject(BoObjectTypes.BoRecordset), _ SAPbobsCOM.Recordset)
oTmpRecordset.DoQuery("Select Count(*) From CUFD Where TableId ='"&  tableName & "' And AliasID = '" & fieldName & "'")
 System.Windows.Forms.Application.DoEvents()
 If CInt(oTmpRecordset.Fields.Item(0).Value) > 0 Then
   UserFieldsExist = True
 Else
  UserFieldsExist = False
 End If System.Runtime.InteropServices.Marshal.ReleaseComObject(oTmpRecordset)
End Function

b.

After data add you must to create a user table and UDO object

Public Sub AddUserTables()
 
 If Not UserTablesExist(userTables(“XX_MARCA”, 0)) Then
   If AddUserTable(userTables(i, 0), _ BoUTBTableType.bott_MasterData, userTables(“XX_MARCA”, “MARCA”)) = 0 Then 
      AddUDO( “XX_MARCA”, “Marca”)
    End If
  End If        
End Sub

Public Function UserTablesExist(ByVal tableName As String) As Boolean
Dim oTmpRecordset As SAPbobsCOM.Recordset

 oTmpRecordset = _ CType(oCompany.GetBusinessObject(BoObjectTypes.BoRecordset), _ SAPbobsCOM.Recordset)
 oTmpRecordset.DoQuery("Select Count(*) From OUTB Where TableName='"& tableName & "'")
 System.Windows.Forms.Application.DoEvents()
 If CInt(oTmpRecordset.Fields.Item(0).Value) > 0 Then
   UserTablesExist = True
 Else
   UserTablesExist = False
 End If   System.Runtime.InteropServices.Marshal.ReleaseComObject( oTmpRecordset)
 oTmpRecordset = Nothing
 GC.Collect()
End Function

Public Function AddUserTable(ByVal tableName As String, _
                             ByVal type As BoUTBTableType, _
                             ByVal tableDescription As String)
 Dim oUserTablesMD As SAPbobsCOM.UserTablesMD
 Dim lretcode As Integer
 Dim errMsg As String = ""

 If String.IsNullOrEmpty(tableDescription) Then
  tableDescription = tableName
 End If

 oUserTablesMD = oCompany.GetBusinessObject(BoObjectTypes.oUserTables)
 oUserTablesMD.TableName = tableName
 oUserTablesMD.TableDescription = tableDescription
 oUserTablesMD.TableType = type
 lretcode = oUserTablesMD.Add
 If lretcode <> 0 Then
   oCompany.GetLastError(lretcode, errMsg)
   MessageBox.Show(errMsg)
 End If
 System.Runtime.InteropServices.Marshal.ReleaseComObject(oUserTablesMD)
 oUserTablesMD = Nothing
 GC.Collect()
 Return lretcode
End Function

Public Function AddUDO(ByVal tableName As String, _
                       ByVal nameAlias As String) As Integer
 Dim oUserObjectMD As SAPbobsCOM.UserObjectsMD
 Dim lretcode As Integer
 Dim errMsg As String = ""

 oUserObjectMD = _ oCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oUserObjectsMD)
 oUserObjectMD.CanCancel = BoYesNoEnum.tYES
 oUserObjectMD.CanClose = BoYesNoEnum.tYES
 oUserObjectMD.CanCreateDefaultForm = BoYesNoEnum.tYES
 oUserObjectMD.CanDelete = BoYesNoEnum.tNO
 oUserObjectMD.CanFind = BoYesNoEnum.tYES
 oUserObjectMD.TableName = tableName
 oUserObjectMD.Code = "O" & tableName
 oUserObjectMD.ManageSeries = BoYesNoEnum.tNO
 oUserObjectMD.Name = "O" & tableName
 oUserObjectMD.ObjectType = BoUDOObjType.boud_MasterData

 oUserObjectMD.FormColumns.FormColumnAlias = "Code"
 oUserObjectMD.FormColumns.FormColumnDescription = "Código"
 oUserObjectMD.FormColumns.Add()

 oUserObjectMD.FormColumns.FormColumnAlias = "Name"
 oUserObjectMD.FormColumns.FormColumnDescription = nameAlias
 oUserObjectMD.FormColumns.Add()
 oUserObjectMD.CanFind = BoYesNoEnum.tYES
 oUserObjectMD.FindColumns.ColumnAlias = "Code"
 oUserObjectMD.FindColumns.Add()
 oUserObjectMD.FindColumns.ColumnAlias = "Name"
 oUserObjectMD.FindColumns.Add()

 lretcode = oUserObjectMD.Add()

 If lretcode <> 0 Then
   oCompany.GetLastError(lretcode, errMsg)
   MessageBox.Show(errMsg)
  End If

  oUserObjectMD = Nothing
  GC.Collect()

  Return lretcode
End Function

For standard we name the UDO object as the same name of the table name. But associated with the prefix “O”. There is not required but makes very ease to remember ant maintain the system.

For the release of SAP (6.80.319) SP:01 PL:22 there have a bug. You must to enter in the menu Tools >UDO> Wizard and force to update any object. If you omit this recommendation the UDO aren’t available for use.

Don't forget

to set corrected values for a oUserObjectMD . If the behaviour of the CFL isn’t correct inspect it.
All of theses steps are called in the first step to deploy a new Add-On. There are a good practice to call it for a new added option main menu.

2.

Add the user table, user object and user form for a valid values.
These step is optional, but recommended to query valid values.
For these step you may to use the standard options in the menu Tools --> UDO --> Standar Forms -->

.
In the sample the

are OXX_MARCA

3.

Add the field into the form 150

These step is implemented in a init method. We recommend to declare a module for each form to manipulate.

In the module you processes all of the events desired for these event (there not is the target for this tutorial).

Of course you implement a FORM_INIT method.

Public Sub FRM150_INIT()
 Dim oItem As SAPbouiCOM.Item
 Dim oStaticText As SAPbouiCOM.StaticText
 Dim oEditText As SAPbouiCOM.EditText
 Dim oFolder As SAPbouiCOM.Folder
 '… put your init code here.
 'In the example we add the field into a separate folder (recommended)
' oTmpForm is a global variable in the module
 oItem = oTmpForm.Items.Add("xx_flropc", SAPbouiCOM.BoFormItemTypes.it_FOLDER)
 oItem.AffectsFormMode = False
 oItemRef = oTmpForm.Items.Item("9")
 oItem.Width = oItemRef.Width + 80
 oFolder = oItem.Specific
 oFolder.Caption = "Options"
 oFolder.GroupWith("9")
 'now add the new field and bind it to the OITM table
  oItem = oTmpForm.Items.Add("U_XX_MARCA", _ SAPbouiCOM.BoFormItemTypes.it_EDIT)
  oItem.AffectsFormMode = True
  oItem.Top = 155
  oItem.Left = 10
  oItem.Width = 100
  oItem.FromPane = 8
  oItem.ToPane = 8
  oEditText = oItem.Specific
  oItem.DisplayDesc = True
  oEditText.DataBind.SetBound(True, "OITM", "U_XX_MARCA")
End Sub

After these step the form is ready to show and update the data into the new added field.

4.

Add the CFL and link it to the new field

The CFL is linked in the after data load event.

Public Sub FRM150_AfterDataLoad(ByVal boi As _ BusinessObjectInfo , ByVal bubbleevent As Boolean)

 Dim oCFLCreationParams As ChooseFromListCreationParams 
 Dim oCFLs As ChooseFromListCollection
 Dim oCFL As ChooseFromList
 Dim oEditTextMarca As SAPbouiCOM.EditText = _
         oTmpForm.Items.Item("U_XX_MARCA").Specific

 oCFLs = oTmpForm.ChooseFromLists
 Try
  oCFLCreationParams = oAplicacion.SBOapp.CreateObject( _
       BoCreatableObjectType.cot_ChooseFromListCreationParams)
  oCFLCreationParams.MultiSelection = False
  oCFLCreationParams.ObjectType = "OXX_MARC"
  oCFLCreationParams.UniqueID = "CFLMRC"
  oCFL = oCFLs.Add(oCFLCreationParams)
 
  oEditTextMarca.ChooseFromListUID = "CFLMRC"
  oEditTextMarca.ChooseFromListAlias = "Code"

 Catch ex As Exception
 End Try
End sub

With these step the values for the new field are linked and restricted to the new user table .

5.

Capture the CFL event and update the selected value

Public Sub FRM150_AFTER(ByVal FormUI As String, _
               ByVal pval As IItemEvent, _
               ByRef BubbleEvent As Boolean)
 Select Case pval.EventType
  Case BoEventTypes.et_CHOOSE_FROM_LIST
   Dim oCFLEvent As SAPbouiCOM.IChooseFromListEvent
   Dim oDataTable As SAPbouiCOM.DataTable = Nothing
   Dim value As String = Nothing
   Dim oEdit As SAPbouiCOM.EditText
  
   oCFLEvent = pval
   oDataTable = oCFLEvent.SelectedObjects
   Try
    value = oDataTable.GetValue(0, 0)
   Catch ex As Exception
   End Try
   If value Is Nothing Then
     Exit Select
   End If
   If Not oCFLEvent.Before_Action Then
    If pval.ItemUID = "U_XX_MARCA" Then
      oEdit = oTmpForm.Items.Item("U_XX_MARCA").Specific
      Try
        'surround these line with a try .. catch block.
       oEdit.String = value 
      Catch ex As Exception
      End Try
     '… place here for another CFL’s
     End If
     oEditText = oTmpForm.Items.Item("7").Specific
     'These step are for force to update mode.
     Try
       oEditText.Value = oEditText.Value
     Catch ex As Exception
     End Try
    BubbleEvent = False  
  End If
'… your code for another after data events
End Sub

Regards

Accepted Solutions (0)

Answers (3)

Answers (3)

rasmuswulff_jensen
Active Contributor
0 Kudos

Hi Alfonso... One addition to your code

oDataTable = oCFLEvent.SelectedObjects

After this line you should test if oDataTable is null/Nothing... Otherwice you will get an error if you ope the choosefrom list but close it by clicking Cancel

Former Member
0 Kudos

Estimados, buen dia

Soy de Peru y nuevo en SDK, podria ser posible me puedan brindar algun manual como para iniciar en SDK, favor estimados, he revisado sus post, pero no logro entender como aplicarlo por lo que me atrevo a pedirles su apoyo con brindarme quizas por ahi un pequeño manual u tutorial para inciarme en este nuevo mundo.

favor de no ser mucha molestia les pediria me puedan compartir algun ejemplo desde el incio como para tratar de aplicarlo en mi ambiente de pruebas.

esperando contar con sus comprensiones quedo a la espera.

Favor cualquier apoyo les pediria me lo hagan llegar a mi correo personal

caldher04@gmail.com

Atte.

Carlos

Former Member
0 Kudos

Hi Alfonso, first of all thanks for your guide.

I'm trying to use it, but i have a problem when i have to get the value from CFL.

The CFL opens, but when i select my value and try to get back to my form (UDO), it happens that other 2 CFL opens and i get "Invalid form" error

I post here the code i've written to handle the et_CHOOSE_FROM_LIST event



Private Sub SBO_Application_ItemEvent(ByVal FormUID As String, ByRef pVal As SAPbouiCOM.ItemEvent, ByRef BubbleEvent As Boolean) Handles SBO_Application.ItemEvent

        Dim oForm As SAPbouiCOM.Form
        Dim oItem As SAPbouiCOM.Item
        Dim oEditText As SAPbouiCOM.EditText

        If (FormUID = "FRDA") Then

            Try                

                oForm = SBO_Application.Forms.Item(FormUID)

                'If (pVal.Before_Action = False) Then

                If pVal.EventType = SAPbouiCOM.BoEventTypes.et_CHOOSE_FROM_LIST Then

                    Dim oCFLEvent As SAPbouiCOM.IChooseFromListEvent
                    Dim oDataTable As SAPbouiCOM.DataTable = Nothing
                    Dim value As String = Nothing
                    Dim oEdit As SAPbouiCOM.EditText

                    oCFLEvent = pVal
                    oDataTable = oCFLEvent.SelectedObjects

                    Try
                        value = oDataTable.GetValue(0, 0)
                    Catch ex As Exception
                    End Try

                    If Not oCFLEvent.Before_Action Then
                        If pVal.ItemUID = "txtCode" Then
                            oEdit = oForm.Items.Item("txtCode").Specific
                            Try
                                'surround these line with a try .. catch block.
                                oEdit.String = value
                            Catch ex As Exception
                            End Try
                        End If
                        oEditText = oForm.Items.Item("txtCode").Specific
                        'These step are for force to update mode.
                        Try
                            oEditText.Value = oEditText.Value
                        Catch ex As Exception
                        End Try
                        BubbleEvent = False
                    End If

                End If
                'End If
            Catch ex As Exception

                If (ex.Message.StartsWith("Cast from") = False) Then

                    'oForm = SBO_Application.Forms.Item(FormUID)
                    'SBO_Application.MessageBox("Error on form" & oForm.UniqueID & " : " & ex.Message)
                    'MessageBox.Show(ex.Message)

                End If

            End Try
        End If

    End Sub

Hope you can help me. I draw my form with Screen Painter and i've bound on it the edittext using the CFL with a user table directly on the screen painter.

I hope i've been clear

Thanks in advance

Nick

former_member185703
Active Contributor
0 Kudos

Hi Alfonso,

I didn't have time yet to look at your sample, but I would like to thank you for sharing your sample with the community + I have linked it to the FAQ in the B1-Wiki: https://wiki.sdn.sap.com/wiki/label/B1/b1_faq

I would suggest that you consider posting it as a Blog...?

Thanks anyway,

Frank

Former Member
0 Kudos

Hello Moebius

make a blog is a very good thing but my english is not good...

I prefer to make how-to 's and post them in the Web.

Let me to consider it

Thank