Crear matrx editable con una UDT

estimados como estan?
me gustaría saber como se puede crear una matrix editable ,es decir, que me permita crear, modificar y eliminar por lineas (celdas), tipo este ejemplo de paises.

tengo este código:

   public void Start()
        {
            string dataTableId = "my_data";
            
          
            // add a data table to the form
            var dataTable = oForm.DataSources.DataTables.Add(dataTableId);

            // add a matrix to the form
            Matrix0 = (SAPbouiCOM.Matrix)oForm.Items.Add(dataTableId, SAPbouiCOM.BoFormItemTypes.it_MATRIX).Specific;
            Matrix0.Item.Width = 700;
            Matrix0.Item.Height = 300;


            // get some data
            //string sql = @"SELECT ""CardCode"", ""CardName"" FROM ""OCRD"" ";
            string sql = @"SELECT ""U_CodigoEDC"", ""U_NombreEDC"" FROM ""@EDICIONESCOL"" ";
            oApp.SetStatusBarMessage("codigo: " + sql);
            dataTable.ExecuteQuery(sql);

            var columns = Matrix0.Columns;

            // create columns
            columns.Add("#", SAPbouiCOM.BoFormItemTypes.it_EDIT);
            columns.Add("Codigo", SAPbouiCOM.BoFormItemTypes.it_EDIT);
            columns.Add("Nombre", SAPbouiCOM.BoFormItemTypes.it_EDIT);

            // setup columns
            columns.Item("#").TitleObject.Caption = "#";
            columns.Item("Codigo").TitleObject.Caption = "Código";
            columns.Item("Nombre").TitleObject.Caption = "Nombre";

            //bind columns to data
            columns.Item("Codigo").DataBind.Bind(dataTableId, "U_CodigoEDC");
            columns.Item("Nombre").DataBind.Bind(dataTableId, "U_NombreEDC");

            // load the data into the rows
            Matrix0.LoadFromDataSource();
            Matrix0.AutoResizeColumns();

            // show form on screen
            oForm.Visible = true;
        }

bueno ademas de esto es lo que necesito poder agregar moificar y eliminar.
cualquier tips o código de ejemplo sera agradecido.
gracias

Hola :grin:

Tienes 2 Opciones:

  1. Cear un UDT tipo “Datos Maestros” y registrarlo como un UDO con las Parametrizaciones de IU como “Formulario por Defecto” y “Estilo de Matriz” y colocarlo en el menu que quieras o dejarlo en la Opcion Herramientas → Formularios por Defecto. Si estas haciendo un AddOn, puedes importar este UDO y crear un UserForm copiando todos los controles y DataSources del UDO (Con esto ahorras tiempo). Pero deberas programar los eventos de Agregar y Eliminar Linea (Menu Contextual sobre la Matrix).

  2. Crear la Matrix desde cero, aca deberas agregar cada columna y asignarle su campo respectivo a traves de un DBDataSource (En el diseñador) o dinamicamente por medio de un DataTable o RecordSet en codigo. Luego deberas usar el Evento “SBO_Application_RightClickEvent” para activar los menus “Agregar Linea” y “Borrar Linea” y finalmente en el Evento “SBO_Application_MenuEvent” programar los eventos de Agregar y Eliminar Linea cuando estos sean seleccionados.

Aqui parte de los codigos:
Activar Menus:

static void SBO_Application_RightClickEvent(ref SAPbouiCOM.ContextMenuInfo eventInfo, out bool BubbleEvent)
        {
            BubbleEvent = true;
            try
            {
                oForm = Application.SBO_Application.Forms.ActiveForm;

                switch (oForm.TypeEx)
                {
                    case "MyAddOn.frmMyFormUser":
                         switch (eventInfo.BeforeAction)
            {
                case true:
                    if (eventInfo.ItemUID != "MatrixID")
                    {
                        oForm.EnableMenu("1292", false); //Desactivar Agregar Linea
                        oForm.EnableMenu("1293", false); //Desactivar Borrar Linea
                    }
                    else
                    {
                        oForm.EnableMenu("1292", true); //Activar Agregar Linea
                        oForm.EnableMenu("1293", true); //Activar Borrar Linea
                    }
                    break;
            }
                        break;
                }
            }
            catch (Exception){}
        }

Agregar / Elimnar Lineas

         static void SBO_Application_MenuEvent(ref SAPbouiCOM.MenuEvent pVal, out bool BubbleEvent)
        {
            BubbleEvent = true;
            try
            {
                oForm = Application.SBO_Application.Forms.ActiveForm;

                switch (oForm.TypeEx)
                {
                    case "MyAddOn.frmMyFormUser":
                        switch (pVal.MenuUID)
                        {
                            case "1292"://Agregar Linea Matrix
                                if (pVal.BeforeAction == true)
                                {
                                    switch (ItemActiveMenu)
                                    {
                                        case "MatrixID":
                                            AddLineMatrixDBDataSource(((SAPbouiCOM.Matrix)oForm.Items.Item("MatrixID").Specific), oForm.DataSources.DBDataSources.Item("@UDT"), "C_0_1");
                                            break;
                                    }
                                }
                                break;
                            case "1293"://Eliminar Linea Matrix
                                if (pVal.BeforeAction == true)
                                {
                                    switch (ItemActiveMenu)
                                    {
                                        case "MatrixID":
                                            oMatrix = ((SAPbouiCOM.Matrix)oForm.Items.Item("MatrixID").Specific);
                                            SAPbouiCOM.DBDataSource oDBDataSource = oForm.DataSources.DBDataSources.Item("@UDT");
                                            int nRow = (int)oMatrix.GetNextSelectedRow(0, SAPbouiCOM.BoOrderType.ot_RowOrder);
                                            oMatrix.FlushToDataSource();
                                            oDBDataSource.RemoveRecord(nRow - 1);
                                            oForm.Mode = SAPbouiCOM.BoFormMode.fm_UPDATE_MODE;
                                            oMatrix.LoadFromDataSource();
                                            BubbleEvent = false;
                                            break;
                                    }
                                }
                                break;
                        }
                        break;
                }
            }
            catch (Exception) { }
        }

 public static void AddLineMatrixDBDataSource(SAPbouiCOM.Matrix oMatrix, SAPbouiCOM.DBDataSource source, string ColumnaFocus = "")
        {
            try
            {
                oMatrix.FlushToDataSource();
                source.InsertRecord(source.Size);
                source.Offset = source.Size - 1;
                oMatrix.LoadFromDataSource();
                oMatrix.SelectRow(source.Size, true, false);
                if (ColumnaFocus.Trim().Length != 0)
                {
                    oEdit = (SAPbouiCOM.EditText)oMatrix.Columns.Item(ColumnaFocus).Cells.Item(source.Size).Specific;
                    oEdit.Active = true;
                    oEdit.Item.Enabled = true;
                }
            }
            catch (Exception) { }
        }

Saludos.

1 me gusta

hola ,muchas gracias Gabriel, eres una fuente inagotable de información, tendré que hacerlo con la segunda opción ya que estoy dentro de un addon, una consulta, despues como deberia llamar a estos eventos en el OnCustomInitialize()?
y lo otro en el

   switch (ItemActiveMenu)

debo hacer lo mismo que decias ayer, ya que dice que no existe el contexto actual?
muchas gracias y perdona las preguntas muy básicas, estoy aprendiendo poco a poco gracias a ti.
saludos,

image

Los Eventos son handles que debes definir en el Program.cs (Se puede hacer directamente en el Form, pero implica mas consideraciones).

En esta seccion del Program.cs debes definir los Handles:

 [STAThread]
        static void Main(string[] args)
        {
            try
            {
                Application oApp = null;
                if (args.Length < 1)
                {
                    oApp = new Application();
                }
                else
                {
                    oApp = new Application(args[0]);
                }
                Menu MyMenu = new Menu();
                MyMenu.AddMenuItems();
                oApp.RegisterMenuEventHandler(MyMenu.SBO_Application_MenuEvent);
                Funciones one = new Funciones();
                Funciones.Conectar_Aplicacion();
                // events handled by SBO_Application_AppEvent 
                Application.SBO_Application.AppEvent += new SAPbouiCOM._IApplicationEvents_AppEventEventHandler(SBO_Application_AppEvent);
                // events handled by SBO_Application_MenuEvent 
                Application.SBO_Application.MenuEvent += new SAPbouiCOM._IApplicationEvents_MenuEventEventHandler(SBO_Application_MenuEvent);
                // events handled by SBO_Application_ItemEvent
                Application.SBO_Application.ItemEvent += new SAPbouiCOM._IApplicationEvents_ItemEventEventHandler(SBO_Application_ItemEvent);
                // events handled by SBO_Application_RightClickEvent
                Application.SBO_Application.RightClickEvent += new SAPbouiCOM._IApplicationEvents_RightClickEventEventHandler(SBO_Application_RightClickEvent);
                // events handled by SBO_Application_FormDataEvent
                Application.SBO_Application.FormDataEvent += new SAPbouiCOM._IApplicationEvents_FormDataEventEventHandler(SBO_Application_FormDataEvent);
                // events handled by SBO_Application_ProgressBarEvent
                Application.SBO_Application.ProgressBarEvent += new SAPbouiCOM._IApplicationEvents_ProgressBarEventEventHandler(SBO_Application_ProgressBarEvent);
                // events handled by SBO_Application_StatusBarEvent
                Application.SBO_Application.StatusBarEvent += new SAPbouiCOM._IApplicationEvents_StatusBarEventEventHandler(SBO_Application_StatusBarEvent);

                oApp.Run();
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
        }

Luego colocar el codigo posteado.

Respecto a la variable “ItemActiveMenu”, es una propiedad tipo String que debes declarar en el Program.cs y asignar en el evento:

static void SBO_Application_RightClickEvent(ref SAPbouiCOM.ContextMenuInfo eventInfo, out bool BubbleEvent)
        {
            BubbleEvent = true;
            ItemActiveMenu = eventInfo.ItemUID;  ///AQUI ASIGNAMOS EL ID DEL ITEM ACTIVO
            try
            {
                oForm = Application.SBO_Application.Forms.ActiveForm;

                switch (oForm.TypeEx)
                {
                    case "MyAddOn.frmMyFormUser":
                         switch (eventInfo.BeforeAction)
            {
                case true:
                    if (eventInfo.ItemUID != "MatrixID")
                    {
                        oForm.EnableMenu("1292", false); //Desactivar Agregar Linea
                        oForm.EnableMenu("1293", false); //Desactivar Borrar Linea
                    }
                    else
                    {
                        oForm.EnableMenu("1292", true); //Activar Agregar Linea
                        oForm.EnableMenu("1293", true); //Activar Borrar Linea
                    }
                    break;
            }
                        break;
                }
            }
            catch (Exception){}
        }

Saludos

1 me gusta

muy bien los acabo de declara en program.cs

             Application.SBO_Application.RightClickEvent += new SAPbouiCOM._IApplicationEvents_RightClickEventEventHandler(SBO_Application_RightClickEvent);
                Application.SBO_Application.MenuEvent += new SAPbouiCOM._IApplicationEvents_MenuEventEventHandler(SBO_Application_MenuEvent)

en cuanto al evento

  static void SBO_Application_RightClickEvent(ref SAPbouiCOM.ContextMenuInfo eventInfo, out bool BubbleEvent)
        {
            BubbleEvent = true;
          SAPbouiCOM.Form oForm;
          string ItemActiveMenu = null; //lo declare asi
          ItemActiveMenu = eventInfo.ItemUID;
            try
            {

                oForm = Application.SBO_Application.Forms.ActiveForm;


                switch (oForm.TypeEx)
                {
                    case "Colaboradores_3.grilaedi": (aca seria el nombre EL formatribute?)
                        switch (eventInfo.BeforeAction)
                        {
                            case true:
                                if (eventInfo.ItemUID != "mted") //aca se pone e nombre de la matrix?
                                {
                                    oForm.EnableMenu("1292", false); //Desactivar Agregar Linea
                                    oForm.EnableMenu("1293", false); //Desactivar Borrar Linea
                                }
                            -...

creo que seria mis preguntas, ya que mi matriz la hice como muestra el codigo al principio, con un sql llene un datatable, y muestra la query, entonces mas que nada esos detalles me quedarian los que anote en el cogido, en serio muhcas gracias Gabriel, la paciencia y todo.
saludos

1 me gusta

ItemActiveMenu los debes declarar como un campo(o propiedad) de la clase Program, no detro del metodo, ya que debe ser usado en varios eventos.

    class Program
    {

        private string ItemActiveMenu = null;

Saludos

1 me gusta

bueno Gabriel gracias, no me reconoces esta propiedad, asi que cree un objeto de la clase Program
Program obj = new Program();
i llame al detro de los eventos
obj.ItemActiveMenu
y asi lo pude reconocer, ahora aun no logro que en el if (eventInfo.ItemUID != “Matrix1”)
me reconozca mi matrix, pero bueno ya lo ire averiguando, gracias por todo como siempre, eres genial Gabriel, sin ti me hubiera demorado quizas cuanto en entender.
gracias

Todo el codigo que publique debe hacerse dentro del Program.cs, no dentro del Form, por lo que colocando a ItemActiveMenu como propiedad de la clase Program deberias poder usarlo en cualquier metodo interno.

Respecto a (eventInfo.ItemUID != “Mi_Matrix”), debe ser el UniqueID del Control, puedes ver que nombre te trae al colocar un BreakPoint en esta linea.

Saludos

1 me gusta

hola Gabriel,
tuve que hacerlo asi ya que lo asigno como me dices (todo el código en program.cs):

 class Program
    {
        
         private string ItemActiveMenu = null;
      


pero me sale ese error, entonces tuve que hacer lo que hice arriba, entonces me funcion con el SBO_Application_RightClickEvent me funciona y aparece la opción de agregar pero cuando voy al quitar linea no funciona, ya que va buscar de nuevo el item ItemActiveMenu y este vuelve nulo, me parece raro que no la agarre tambien… bueno igual sigo en esto, gracias Gabriel

1 me gusta

Oh sorry! mi tonto error :rofl:, si los metodos son static la propiedad para ser usada dentro de ellos tambien debe serlo.

class Program
    {
        
         private static string ItemActiveMenu = null;
2 Me gusta

jaja no te preocupes, eso me pasa por ser novato igual, otros se hubieran dado cuenta:
ultimas dos coss y no molesto mas lo juro xd,
AddLineMatrixDBDataSource(((SAPbouiCOM.Matrix)oForm.Items.Item("my_data").Specific), oForm.DataSources.DBDataSources.Item("@EDICIONESCOL"), "U_CodigoEDC");

si yo use un datatable en vez de un dbdatasources igual funcionaria esta linea?
, lo otro para actualizar para agregar una linea no me daja agregar una linea en parte de abajo solo me toma la ultima linea que tiene datos



y lo ultimo para actualizar por celda tendria que darle otro evento que actualice lo modificado en alguna de las celdas de la linea?

muchas gracias Gabriel, no sabia esto bien de los eventos y realmente son muy utiles, muchas gracias.

1 me gusta

Hola!

Agrega un nuevo tema de “Como Agregar Registros a un DataTable” para responder alli y mantener el foro ordenado.

Gracias!:grin:

2 Me gusta

Este tema se cerró automáticamente 7 días después del último post. No se permiten nuevas respuestas.