You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在SAP B1的UDO矩阵中实现物料代码多选?

我太懂这种无奈了——SAP B1里UDO矩阵的原生UDV确实只支持单选,批量选物料的时候效率低到让人抓狂。之前帮朋友解决过类似的问题,核心思路是绕开原生UDV的限制,自己做一个带复选框的多选物料弹窗,然后把选中的物料批量塞回UDO矩阵里。下面是具体的实现方案和代码,你可以直接参考调整:

解决方案思路

原生UDV没有批量多选的接口,所以我们需要:

  1. 拦截UDV的触发事件,不让原生弹窗出来
  2. 自己创建一个带复选框的自定义表单,加载所有可选物料
  3. 用户勾选完物料后,把选中的条目批量添加到UDO矩阵中(还要避免重复添加)
具体代码实现

首先,在你的主表单ItemEvent里拦截UDV的点击事件:

Private Sub SBO_Application_ItemEvent(ByVal FormUID As String, ByRef pVal As SAPbouiCOM.ItemEvent, ByRef BubbleEvent As Boolean) Handles SBO_Application.ItemEvent
    ' 替换成你实际的UDO表单UID、矩阵ID和物料代码列ID
    Const UDO_FORM_UID As String = "UDO_MY_FORM"
    Const MATRIX_ID As String = "mtxItems"
    Const ITEM_CODE_COL_ID As String = "colItemCode"

    ' 判断是否是点击了物料代码列的UDV
    If pVal.FormUID = UDO_FORM_UID AndAlso pVal.ItemUID = MATRIX_ID AndAlso pVal.ColUID = ITEM_CODE_COL_ID Then
        If pVal.EventType = SAPbouiCOM.BoEventTypes.et_CLICK AndAlso pVal.BeforeAction Then
            ' 取消原生UDV弹窗
            BubbleEvent = False
            ' 打开自定义多选物料表单
            OpenMultiItemSelectForm()
        End If
    End If
End Sub

然后实现打开多选表单的方法,这里会创建一个带矩阵和复选框的弹窗,加载所有有效物料:

Private Sub OpenMultiItemSelectForm()
    Dim oForm As SAPbouiCOM.Form
    Dim oMatrix As SAPbouiCOM.Matrix
    Dim oItem As SAPbouiCOM.Item
    Dim oRS As SAPbobsCOM.Recordset
    Dim rowIndex As Integer = 1

    ' 先检查表单是否已打开,避免重复创建
    Try
        oForm = SBO_Application.Forms.Item("FRM_MULTI_ITEM_SELECT")
        oForm.Visible = True
        Exit Sub
    Catch
        ' 表单不存在,创建新表单
    End Try

    ' 创建表单参数
    Dim formParams As SAPbouiCOM.FormCreationParams = SBO_Application.CreateObject(SAPbouiCOM.BoCreatableObjectType.cot_FormCreationParams)
    formParams.UniqueID = "FRM_MULTI_ITEM_SELECT"
    formParams.FormType = "MTX_ITEM_SELECT"
    formParams.BorderStyle = SAPbouiCOM.BoFormBorderStyle.fbs_Sizable
    oForm = SBO_Application.Forms.AddEx(formParams)

    ' 设置表单属性
    oForm.Title = "批量选择物料"
    oForm.SetBounds(150, 150, 650, 450)

    ' 添加物料矩阵
    oItem = oForm.Items.Add("mtxItems", SAPbouiCOM.BoFormItemTypes.it_MATRIX)
    oItem.SetBounds(15, 15, 620, 360)
    oMatrix = oItem.Specific

    ' 配置矩阵列:复选框、物料代码、物料名称
    With oMatrix.Columns
        ' 复选框列
        .Add("colSelect", SAPbouiCOM.BoFormItemTypes.it_CHECK_BOX).Width = 70
        .Item("colSelect").TitleObject.Caption = "选择"

        ' 物料代码列
        .Add("colItemCode", SAPbouiCOM.BoFormItemTypes.it_EDIT).Width = 180
        .Item("colItemCode").TitleObject.Caption = "物料代码"
        .Item("colItemCode").Editable = False

        ' 物料名称列
        .Add("colItemName", SAPbouiCOM.BoFormItemTypes.it_EDIT).Width = 360
        .Item("colItemName").TitleObject.Caption = "物料名称"
        .Item("colItemName").Editable = False
    End With

    ' 加载所有有效物料到矩阵
    oRS = SBO_Application.Company.GetBusinessObject(SAPbobsCOM.BoObjectTypes.BoRecordset)
    ' 可以修改查询条件,比如筛选特定物料组、库存不为0的物料等
    oRS.DoQuery("SELECT ItemCode, ItemName FROM OITM WHERE ValidFor = 'Y' ORDER BY ItemCode")

    If oRS.RecordCount > 0 Then
        oMatrix.RowCount = oRS.RecordCount
        Do While Not oRS.EoF
            oMatrix.Columns.Item("colItemCode").Cells.Item(rowIndex).Specific.Value = oRS.Fields("ItemCode").Value
            oMatrix.Columns.Item("colItemName").Cells.Item(rowIndex).Specific.Value = oRS.Fields("ItemName").Value
            rowIndex += 1
            oRS.MoveNext()
        Loop
    End If

    ' 添加确定和取消按钮
    oItem = oForm.Items.Add("btnConfirm", SAPbouiCOM.BoFormItemTypes.it_BUTTON)
    oItem.SetBounds(500, 390, 80, 25)
    oItem.Specific.Caption = "确定"

    oItem = oForm.Items.Add("btnCancel", SAPbouiCOM.BoFormItemTypes.it_BUTTON)
    oItem.SetBounds(410, 390, 80, 25)
    oItem.Specific.Caption = "取消"

    ' 注册多选表单的事件处理
    AddHandler SBO_Application.ItemEvent, AddressOf MultiSelectForm_ItemHandler
End Sub

最后是多选表单的按钮事件处理,负责把选中的物料添加到UDO矩阵:

Private Sub MultiSelectForm_ItemHandler(ByVal FormUID As String, ByRef pVal As SAPbouiCOM.ItemEvent, ByRef BubbleEvent As Boolean)
    If FormUID <> "FRM_MULTI_ITEM_SELECT" Then Exit Sub

    If pVal.EventType = SAPbouiCOM.BoEventTypes.et_ITEM_PRESSED AndAlso Not pVal.BeforeAction Then
        Select Case pVal.ItemUID
            Case "btnConfirm"
                Dim oMultiForm As SAPbouiCOM.Form = SBO_Application.Forms.Item(FormUID)
                Dim oMultiMatrix As SAPbouiCOM.Matrix = oMultiForm.Items.Item("mtxItems").Specific
                Dim oUDOForm As SAPbouiCOM.Form = SBO_Application.Forms.Item("UDO_MY_FORM") ' 替换成你的UDO表单UID
                Dim oUDOMatrix As SAPbouiCOM.Matrix = oUDOForm.Items.Item("mtxItems").Specific ' 替换成你的UDO矩阵ID

                ' 遍历多选矩阵,处理选中的物料
                For row As Integer = 1 To oMultiMatrix.RowCount
                    Dim chkBox As SAPbouiCOM.CheckBox = oMultiMatrix.Columns.Item("colSelect").Cells.Item(row).Specific
                    If chkBox.Checked Then
                        Dim itemCode As String = oMultiMatrix.Columns.Item("colItemCode").Cells.Item(row).Specific.Value
                        Dim itemName As String = oMultiMatrix.Columns.Item("colItemName").Cells.Item(row).Specific.Value

                        ' 检查UDO矩阵中是否已存在该物料,避免重复
                        Dim isDuplicate As Boolean = False
                        For udoRow As Integer = 1 To oUDOMatrix.RowCount
                            If oUDOMatrix.Columns.Item("colItemCode").Cells.Item(udoRow).Specific.Value = itemCode Then
                                isDuplicate = True
                                Exit For
                            End If
                        Next

                        If Not isDuplicate Then
                            ' 添加新行到UDO矩阵
                            oUDOMatrix.AddRow()
                            Dim newRow As Integer = oUDOMatrix.RowCount
                            oUDOMatrix.Columns.Item("colItemCode").Cells.Item(newRow).Specific.Value = itemCode
                            ' 如果需要自动填充物料名称,这里直接赋值
                            oUDOMatrix.Columns.Item("colItemName").Cells.Item(newRow).Specific.Value = itemName
                        End If
                    End If
                Next

                ' 关闭多选表单
                oMultiForm.Close()
                ' 移除事件绑定,避免内存泄漏
                RemoveHandler SBO_Application.ItemEvent, AddressOf MultiSelectForm_ItemHandler

            Case "btnCancel"
                SBO_Application.Forms.Item(FormUID).Close()
                RemoveHandler SBO_Application.ItemEvent, AddressOf MultiSelectForm_ItemHandler
        End Select
    End If
End Sub
注意事项
  1. 一定要替换代码中所有占位符(比如UDO_MY_FORMmtxItems等)为你实际的表单、矩阵和列ID
  2. 可以修改物料查询的SQL语句,比如添加WHERE ItemGroupCode = X来筛选特定组的物料,或者加入库存条件
  3. 如果你的UDO矩阵有其他需要自动填充的字段(比如单位、价格),可以在添加行时通过查询OITM/OITB等表获取数据后填充
  4. 记得测试权限问题,确保用户有打开自定义表单和修改UDO矩阵的权限

内容的提问来源于stack exchange,提问作者Schadrack Rurangwa

火山引擎 最新活动