none
Listox al mover hacia arriba o visceversa se me actualice el no de orden consecutivos en asp.net c# RRS feed

  • Pregunta

  • Buenas tardes:

    muevo mi no_producto hacia arriba entonces el de abajo queda con el mismo numero ejemplo:

    3 este se resta entonces tambien queda en 2

    2

    no se como hacer que no se repitan, revisa mi codigo a ver si ven una solucion,tal vez al hacer el selected de listbox cuando se mueva una para arriba el de abajo se incrmente?aun no se como hacerle

    *para subir un no y restarle y estar arriba.

    protected void btnarriba_Click1(object sender, EventArgs e)

        {
            int index = lsblista.SelectedIndex;
            lsblista.Items.Insert(lsblista.SelectedIndex - 1, lsblista.SelectedItem.ToString());
            lsblista.Items.RemoveAt(index + 1);
            SqlConnection con = new SqlConnection(sql);
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "Incremento";
            cmd.Parameters.Add("@id", SqlDbType.Int).Value = lbli.Text.Trim();
            cmd.Parameters.Add("@no_producto", SqlDbType.Int).Value = lblp_cli.Text.Trim();
            cmd.Parameters.Add("@nombre", SqlDbType.VarChar).Value = txtnom.Text.Trim();
           
            cmd.Connection = con;
            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
                Response.Write("Record Update successfully");
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                con.Close();
                con.Dispose();
            }   

    *Store Procedure:

    *de subir: UPDATE Cat_Tipo_Contenedor SET nombre=@nombre, no_producto=@no_producto-1 where id=@id

    *de bajar: update  Cat_Tipo_Contenedor SET nombre=@nombre, no_producto=@no_producto+1 where id=@id

    *para al que quedo abajo sumarle un mas  en lugar del que subi tome su lugar:

           

    *boton para abajo

    int index = lsblista.SelectedIndex;
            lsblista.Items.Insert(lsblista.SelectedIndex + 1, lsblista.SelectedItem.ToString());
            lsblista.Items.RemoveAt(index - 1);
            SqlConnection con = new SqlConnection(sql);
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "Decremento";
           cmd.Parameters.Add("@id", SqlDbType.Int).Value = lbli.Text.Trim();
            cmd.Parameters.Add("@no_producto", SqlDbType.Int).Value = lblp_cli.Text.Trim();
            cmd.Parameters.Add("@nombre", SqlDbType.VarChar).Value = txtnom.Text.Trim();

            cmd.Connection = con;
            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
                Response.Write("Record Update successfully");
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                con.Close();
                con.Dispose();
            }

    jueves, 17 de marzo de 2016 0:08

Respuestas

  • No programo vn.net, así que le dejo cualquier traducción a usted (desde C#).

    Sería como le dije antes:  Después de correr el PA sabemos que potencialmente muchos valores de no_producto han cambiado.  Lo más sano es recargar la lista desde base de datos.  El mismo PA puede hacer un SELECT de la tabla como último paso.

    No importa qué se muestra en el listbox, igualmente usted puede tener el ID (clave primaria) y ubicar el elemento correspondiente en el listbox.


    Jose R. MCP
    Code Samples

    jueves, 17 de marzo de 2016 15:40
    Moderador

Todas las respuestas

  • Pues no sé si ya estará dispuesta a escucharme, pero bueno, igualmente le respondo.

    Como le dije en su pregunta anterior, la lógica no es fácil pero no es demasiado complicada.  Como le dije antes, si no son demasiados registros, puede usar el widget Sortable de jQuery UI.  Pero bueno, ese será otro tema.

    Pasemos a la pregunta:  ¿Cómo reordenar un elemento en una colección?  Como almacena la colección en una tabla de SQL Server, el asunto es bien fácil.

    Create Procedure dbo.spMoverRegistro
    	@id int
    	, @nuevaPos int
    AS
    BEGIN
    	Set NoCount On;
    	
    	--Veamos cómo se mueve el registro:  Si hacia arriba o hacia abajo.
    	Declare @posActual int;
    	SELECT
    		@posActual = columna_orden
    	FROM
    		tabla
    	WHERE
    		ID = @id
    	;
    	--No hacemos nada si la posición nueva es igual a la actual.
    	If (@nuevaPos = @posActual) return 0;
    	Declare @haciaArriba bit = Case When @nuevaPos - @posActual > 0 Then 0 Else 1 End;
    	If (@haciaArriba = 1)
    	BEGIN
    		UPDATE tabla
    		SET
    			columna_orden = columna_orden + 1
    		WHERE
    			columna_orden >= @nuevaPos
    			AND
    			columna_orden < @posActual
    			AND
    			ID <> @id
    		;
    	End
    	ELSE
    	BEGIN
    		UPDATE tabla
    		SET
    			columna_orden = columna_orden - 1
    		WHERE
    			columna_orden <= @nuevaPos
    			AND
    			columna_orden > @posActual
    			AND
    			ID <> @id
    		;
    	End
    	--Listo.  Solamente resta actualizar el item que se modificó.
    	UPDATE tabla
    	SET
    		columna_orden = @nuevaPos
    	WHERE
    		ID = @id
    	;
    	return 0;
    End
    


    Por supuesto el código que muestro aquí no lo he probado, pero confío en que le servirá bien, al menos para ilustrar el algoritmo.

    Nótese que el algoritmo asume que la columna de ordenamiento no tiene faltantes en la numeración.  Es decir que si hay 555 registros en la tabla, los valores en la columna van de 1 a 555 sin faltar ninguno.  Si gusta le puedo mostrar un script de T-SQL que se asegura de que esto sea así.


    Jose R. MCP
    Code Samples


    jueves, 17 de marzo de 2016 6:15
    Moderador
  • Buenos dias: seria asi?

    Create Procedure dbo.spMoverRegistro @id int ****aqui seria mi id por default , @nuevaPos int****aqui este que una nueva columan o la de no_producto AS BEGIN Set NoCount On; --Veamos cómo se mueve el registro: Si hacia arriba o hacia abajo. Declare @posActual int; SELECT @posActual = columna_orden****aqui la columna de no_producto FROM tabla WHERE ID = @id ; --No hacemos nada si la posición nueva es igual a la actual. If (@nuevaPos = @posActual) return 0; Declare @haciaArriba bit = Case When @nuevaPos - @posActual > 0 Then 0 Else 1 End; If (@haciaArriba = 1) BEGIN UPDATE tabla SET columna_orden = columna_orden + 1 WHERE columna_orden >= @nuevaPos AND columna_orden < @posActual AND ID <> @id ; End ELSE BEGIN UPDATE tabla SET columna_orden = columna_orden - 1 WHERE columna_orden <= @nuevaPos AND columna_orden > @posActual AND ID <> @id ; End --Listo. Solamente resta actualizar el item que se modificó. UPDATE tabla SET columna_orden = @nuevaPos WHERE ID = @id ; return 0; End

    ****y en mi codigo vb.net: seria asi?...

      int index = lsblista.SelectedIndex;
            lsblista.Items.Insert(lsblista.SelectedIndex - 1, lsblista.SelectedItem.ToString());
            lsblista.Items.RemoveAt(index + 1);
            SqlConnection con = new SqlConnection(sql);
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "MoverRegistros";
            cmd.Parameters.Add("@id", SqlDbType.Int).Value = lbli.Text.Trim();
            cmd.Parameters.Add("@no_producto", SqlDbType.Int).Value = lblp_cli.Text.Trim();
            cmd.Parameters.Add("@nombre", SqlDbType.VarChar).Value = txtnom.Text.Trim();
           
            cmd.Connection = con;
            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
                Response.Write("Record Update successfully");
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                con.Close();
                con.Dispose();
            }   

    jueves, 17 de marzo de 2016 14:47
  • Hola.  El parámetro @id es la clave primaria del registro que se está moviendo hacia arriba o hacia abajo.  El parámetro @nuevaPos es el nuevo valor de la columna de ordenamiento.  Yo la llamé columna_orden en el PA, pero creo que usted le llama no_producto (que es un poco confuso para serle sincero).

    Luego lo que usted muestra en negrita para su listbox no me parece correcto.  Parece que está asumiendo que la posición nueva varió en 1 unidad solamente cuando en realidad pudo haber variado mucho más.  ¿Cuál es el propósito de ese código para lsblista?  ¿Reubicar el item?  Yo le soy muy sincero y mejor después de correr el PA recargaría el LB completo desde base de datos.  ¿Por qué?  Porque los valores de orden de potencialmente muchos otros items también cambiaron.  Si gusta puede recordar el @id y ubicar el elemento en el LB correspondiente a ese @id y seleccionarlo para que la interfase gráfica "quede como el usuario la tenía" antes de guardar el cambio.


    Jose R. MCP
    Code Samples

    jueves, 17 de marzo de 2016 14:54
    Moderador
  • El proposito del listbox,es que al seleccionar un item este lo mueva para arriba o abajo y se modifique su no_producto y los que deabajo cambien su numero, la cuestios tambien es la siguiente en el listbox solo muestro el no_producto y su nombre NO EL ID por presentacion de vista al usuarios,asi que yo modifico el listbox apartir de su no_producto.

    ok, haci se hace el store, y como seria asi como te digo en el listbox desde vb.net?

    jueves, 17 de marzo de 2016 15:01
  • No programo vn.net, así que le dejo cualquier traducción a usted (desde C#).

    Sería como le dije antes:  Después de correr el PA sabemos que potencialmente muchos valores de no_producto han cambiado.  Lo más sano es recargar la lista desde base de datos.  El mismo PA puede hacer un SELECT de la tabla como último paso.

    No importa qué se muestra en el listbox, igualmente usted puede tener el ID (clave primaria) y ubicar el elemento correspondiente en el listbox.


    Jose R. MCP
    Code Samples

    jueves, 17 de marzo de 2016 15:40
    Moderador
  • Aok, es que el foro esta enfocado asp.net
    jueves, 17 de marzo de 2016 16:17