Usuario
Consulta de Agregar Valores de DGV a la tabla sql

Pregunta
-
Tengo el codigo:
Dim textosqIngresa As New String(CType("Insert into DetalleOrden (NumOrden,CodigoArticulo,UnidadMedida,PrecioUnitario,Cantidad,Descuento)values(@NumOrden,@CodigoArticulo,@UnidadMedida,@PrecioUnitario,@Cantidad,@Descuento)", Char())) Dim cmda As New SqlCommand(textosqIngresa, conex) conex.Open() Dim fila As DataGridViewRow = New DataGridViewRow() Try For Each fila In dgvDatos.Rows cmda.Parameters.Clear() cmda.Parameters.AddWithValue("@NumOrden", txtNumeroOrden.Text) cmda.Parameters.AddWithValue("@CodigoArticulo", Convert.ToString(fila.Cells("CodigoArticulo").Value)) cmda.Parameters.AddWithValue("@UnidadMedida", Convert.ToString(fila.Cells("UnidadMedida").Value)) cmda.Parameters.AddWithValue("@PrecioUnitario", Convert.ToString(fila.Cells("PrecioUnitario").Value)) cmda.Parameters.AddWithValue("@Cantidad", Convert.ToString(fila.Cells("Cantidad").Value)) cmda.Parameters.AddWithValue("@Descuento", Convert.ToString(fila.Cells("Descuento").Value)) Next MessageBox.Show("Orden Guardada Correctamente", "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Information) Catch ex As Exception If conex.State = ConnectionState.Open Then cmda.ExecuteNonQuery() End If conex.Close() End Try Call Limpiar() Me.Close() Catch ex As Exception MessageBox.Show("Error al agregar", "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Information) Finally conex.Close() End Try
y el diseño:
Las Tablas son Orden y DetalleOrden, lo que es cabecera si me guarda el problema es con el contenido del datagridview, el codigo del articulo esta no visible y la tabla es:
Cual es el error que no esta guardando?
JackJJ Piura - Peru
Todas las respuestas
-
Intente con lo siguiente:
Dim InstruccionInsert As String = "INSERT INTO DetalleOrden (NumOrden, CodigoArticulo, UnidadMedida, PrecioUnitario, Cantidad, Descuento)VALUES(@NumOrden, @CodigoArticulo, @UnidadMedida, @PrecioUnitario, @Cantidad, @Descuento)" conex.Open() Try For Each fila As DataGridViewRow In dgvDatos.Rows Dim cmda As New SqlCommand(InstruccionInsert, conex) cmda.Parameters.Clear() cmda.Parameters.AddWithValue("@NumOrden", txtNumeroOrden.Text) cmda.Parameters.AddWithValue("@CodigoArticulo", Convert.ToString(fila.Cells("CodigoArticulo").Value)) cmda.Parameters.AddWithValue("@UnidadMedida", Convert.ToString(fila.Cells("UnidadMedida").Value)) cmda.Parameters.AddWithValue("@PrecioUnitario", Convert.ToString(fila.Cells("PrecioUnitario").Value)) cmda.Parameters.AddWithValue("@Cantidad", Convert.ToString(fila.Cells("Cantidad").Value)) cmda.Parameters.AddWithValue("@Descuento", Convert.ToString(fila.Cells("Descuento").Value)) cmda.ExecuteNonQuery() Next conex.Close() MessageBox.Show("Orden Guardada Correctamente", "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Information) Catch ex As Exception 'Mensaje con la excepción End Try
Veo que @PrecioUnitario, @Cantidad y @Descuento lo convierte a cadena ¿por alguna razón en especial? Debería convertir a un tipo valido, para ello tiene Convert.ToInt32, Convert.ToDecimal(), etc
Discúlpeme por no dar mayores detalles pero ando muy copado de tiempo, si tiene alguna duda puntual no dude en comentarlo.
- Editado Willams Morales jueves, 26 de mayo de 2016 23:58
-
Hola, no se preocupe. No me percate de ese tema de echo esos valores en la tabla son numeric con dos decimales entonces sera a decimal verificare eso.
Parece que ya esta, pero al revisar la tabla no guarda nada sale vacio el detalle
JackJJ Piura - Peru
- Editado AcuTau viernes, 27 de mayo de 2016 1:52
-
-
Le voy a dar una recomendación y espero lo tomé a toda regla: no es correcto abrir conexiones sin un control de su ámbito. Fíjese que primero abre una conexión y se la asigna al objeto SqlCommand, luego cierra la conexión, posteriormente vuelve abrir la conexión y a reutilizar el objeto SqlCommand, pero al cerrar la conexión ya perdió el vínculo, como ve es una mala practica. Le sugiero haga uso de la instrucción using para enmarcar una conexión en un ámbito estricto de uso, además con la instrucción using ya no es necesario validar el estado de la conexión antes de abrirla y tampoco es necesario cerrar la conexión, todo eso lo maneja using (creo haberle comentado esto). Si quiere evitarse problemas como los que está teniendo cambie su código bajo la siguiente estructura:
Cabecera:
Using cn As New SqlConnection("CADENA_CONEXION") Dim consultaSQL As String = "INSERT INTO MiTabla VALUES (@Valor1, Valor2)" Using cmd As New SqlCommand(consultaSQL, cn) cmd.Parameters.AddWithValue("@Valor1", Valor1) cmd.Parameters.AddWithValue("@Valor2", Valor1) cn.Open() cmd.ExecuteNonQuery() End Using End Using
Detalles:
Using cn As New SqlConnection("CADENA_CONEXION") cn.Open() Dim consultaSQL As String = "INSERT INTO MiTabla VALUES (@Valor1, Valor2)" For Each row As DataGridViewRow In DataGridView1.Rows Using cmd As New SqlCommand(consultaSQL, cn) cmd.Parameters.Clear() cmd.Parameters.AddWithValue("@Valor1", row.Cells(0).Value.ToString()) cmd.Parameters.AddWithValue("@Valor2", row.Cells(1).Value.ToString()) cmd.ExecuteNonQuery() End Using Next End Using
Haga los cambios y comenteme como le fue.
-
¿Dónde está cargando los datos al objeto orden? Al parecer está intentando utilizar un objeto de tipo DetalleOrden que no ha sido inicializado, debería tener algo como lo siguiente:
Dim orden As New OrdenDE() orden.Codigo = valor orden.Proveedor = valor ... orden.DetalleOrden = New DetalleOrden() orden.DetalleOrden.CodigoOrden = valor ...
-
La parte de
Al inicio de todo el codigo luego del Public Class frmRegistroOrden
tengo : Dim listado As New List(Of DetalleOrdenBE)
Dim orden As New OrdenDE() orden.Codigo = valor orden.Proveedor = valor ...
es la que esta arriba de try a eso te refieres?
Dim orden As New OrdenDE <------ orden.Autorizador = New AutorizadorBE(Me.cboAutorizador.SelectedValue) orden.Proveedor = New ProveedorBE(Me.cboProveedor.SelectedValue) orden.ModoPago = IIf(Me.cboModoPago.Text = "BANCO", "B", "E") orden.Moneda = IIf(Me.cboMoneda.Text = "SOLES", "S", "D") orden.TipoCambio = IIf(Me.cboMoneda.Text = "SOLES", 1, Me.txtTipoCambio.Text) orden.FechaOrden = Me.dtpFechaOrden.Value orden.FechaEntrega = Me.dtpFechaEntrega.Value orden.FechaPago = IIf(Me.cbxCredito.Checked = False, Me.dtpFechaOrden.Value, Me.dtpFechaPago.Value) orden.DireccionEntrega = Me.txtDireccion.Text.Trim orden.Estado = "PENDIENTE" orden.Referencia = Me.txtReferencia.Text.Trim orden.SubTotal = CDbl(Me.txtSubtotal.Text) orden.Igv = CDbl(Me.txtIGV.Text) orden.Total = CDbl(Me.txtTotal.Text) orden.PorcentajeImpuesto = 18 '18% orden.Credito = Me.cbxCredito.Checked orden.DetalleOrden = listado Try OrdenSV.GuardarOrden(orden) MessageBox.Show("Orden Guardada Correctamente", "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Information) Me.Close() Catch ex As Exception MessageBox.Show(ex.Message, "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Stop) End Try
y en el boton agregar parte del resto esta :
Dim detalle As New DetalleOrdenBE <----- detalle.CodigoArticulo = Me.lblCodigoArt.Text detalle.Descripcion = Me.txtArticulo.Text detalle.PrecioUnitario = CDbl(Me.txtPrecio.Text) detalle.Cantidad = CDbl(Me.txtCantidad.Text) detalle.Descuento = IIf(Me.txtDescuento.Text.Trim = "", 0.0, CDbl(Me.txtDescuento.Text)) detalle.UnidadMedida = Me.txtUnidadMedida.Text detalle.Importe = Math.Round((Me.txtPrecio.Text * Me.txtCantidad.Text) - Me.txtDescuento.Text, 2) listado.Add(detalle) Me.dgvDatos.DataSource = Nothing Me.dgvDatos.AutoGenerateColumns = False Me.dgvDatos.DataSource = listado CalcularTotales() Me.lblCodigoArt.Text = "" Me.txtArticulo.Text = "" Me.txtUnidadMedida.Text = "" Me.txtPrecio.Text = "0.00" Me.txtCantidad.Text = "1" Me.txtDescuento.Text = "0.00" Me.btnBuscar.Focus()
JackJJ Piura - Peru
- Editado AcuTau viernes, 27 de mayo de 2016 17:39
-
Hola que tal, buen día.
No sé si ya pudiste resolver tu problema, no tengo mucha experiencia con VB, por ello no colocaré código, sin embargo puedo darte algunos consejos que me han servido.
Si usas el gestor de Microsoft SQL Server, puedes crear un procedimiento almacenado y después usar ese procedimiento en tu código.
https://msdn.microsoft.com/es-mx/library/cc464057%28v=vs.71%29.aspx
Si prefieres hacerlo en el código, los pasos serían, crear la conexión llenar los datos en el datagrid y despues recorrer cada fila del datagrid para obtener los registros e insertarlos en tu BD.
Aquí te puedes auxiliar:
http://www.forosdelweb.com/f29/como-pasar-datos-datagridview-base-datos-sql-1008191/
El error de referencia no establecida es como mencionan antes, porque no se ha inicializado, la forma de hacerlo es primero declarar un objeto del tipo de tu clase y después usarlo. Claro que esto ya lo dominas solo que se nos llega a pasar a veces :) y donde creo es el error es porque le dices esto:
//Lo correcto creo sería crear un objeto de tipo OrdenSV
DIM objeto AS New Orden.SV()
y luego usarlo
objeto.GuardarOrden(orden)
Así sucesivamente son las demás instrucciones
Try OrdenSV.GuardarOrden(orden) MessageBox.Show("Orden Guardada Correctamente", "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Information) Me.Close() Catch ex As Exception MessageBox.Show(ex.Message, "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Stop) End Try
que a su vez llama a este, donde no se declara el objeto OrdenSave
Public Class OrdenSV Public Shared Sub GuardarOrden(ByVal orden As OrdenDE) OrdenSave.GuardarOrden(orden) End Sub End Class
Y a su vez llama a esto
Public Class OrdenSave Public Shared Sub GuardarOrden(ByVal orden As OrdenDE) Using conex As New SqlConnection(ConfigurationManager.ConnectionStrings("default").ToString) Dim textosqIngresar As New String(CType("Insert into Orden (NumOrden,Tipo,Proveedor,Autorizador,ModoPago,Moneda,TipoCambio,Destino,Usuario,FechaOrden,FechaEntrega,FechaPago,DireccionEntrega,Estado,Referencia,SubTotal,Igv,Total,PorcentajeImpuesto,Credito)values(@NumOrden,@Tipo,@Proveedor,@Autorizador,@ModoPago,@Moneda,@TipoCambio,@Destino,@Usuario,@FechaOrden,@FechaEntrega,@FechaPago,@DireccionEntrega,@Estado,@Referencia,@SubTotal,@Igv,@Total,@PorcentajeImpuesto,@Credito)", Char())) Dim cmd As New SqlCommand(textosqIngresar, conex) ....
Saludos.
Hasta Siempre.... Erick Martínez.
- Editado hserick viernes, 27 de mayo de 2016 17:21 error en código para declarar objeto
-
Aun no lo he podido solucionar
Segun lo que me dices obvio me va salir error si yo hago lo que dices pasa esto, porque es una clase de donde lo llamo y si hago lo que dices sale esto:
Quizas sera de ver con store procedure mmm pero ya que estoy lo tengo hecho que es lo mismo deberia ver el error nomas.
Gracias
JackJJ Piura - Peru
- Editado AcuTau viernes, 27 de mayo de 2016 19:09
-
-
Que extenso este Post, no pude leerlo todo.
Al encerrar la declaración del objeto Connection entre un bloque Using ... End Using, nos estaremos asegurando de cerrar la conexión y de destruir los recursos utilizados por el objeto, al finalizar dicho bloque (cuando se ejecute End Using). Con ésto no tenemos que estar pendientes de llamar al método Close (para cerrar la conexión), ni tampoco al método Dispose (para destruir el objeto), por tanto, no es necesario disponer de un procedimiento externo para tales menesteres.
En un solo método puedes Guardar Cabecera/Detalle/Restar Stock y es una sola conexión
Public Sub GrabarVenta(ByVal ven As E.clsVentaE, ByVal dven As E.clsDetalleVentaE, ByVal DBArt As E.clsDetalleBodegaArticuloE, ByVal codDetMov As Integer, ByVal codMovi As Integer, ByVal codUser As String, ByVal codAfectado As Integer) Using cn As DbConnection = clsConexionAD.Conectar cn.Open() Dim t As DbTransaction = cn.BeginTransaction Dim cmd As DbCommand = cn.CreateCommand cmd.Transaction = t cmd.CommandText = "xspInsertarVenta" cmd.CommandType = CommandType.StoredProcedure With cmd.Parameters .Add(CreateParameter("@idVenta", DbType.Int32, ven.IdVenta)) .Add(CreateParameter("@idCliente", DbType.Int32, ven.IdCliente)) .Add(CreateParameter("@idTipoDocumento", DbType.Int32, ven.IdTipoDocumento)) .Add(CreateParameter("@ptoCodigo", DbType.AnsiString, ven.PtoCodigo, 3)) .Add(CreateParameter("@locCodigo", DbType.AnsiString, ven.LocCodigo, 3)) .Add(CreateParameter("@numFactura", DbType.AnsiString, ven.NumFactura, 18)) .Add(CreateParameter("@autorizacion", DbType.AnsiString, ven.Autorizacion, 15)) .Add(CreateParameter("@subTotal", DbType.Single, ven.SubTotal)) .Add(CreateParameter("@valorIva", DbType.Single, ven.ValorIva)) .Add(CreateParameter("@total", DbType.Single, ven.Total)) .Add(CreateParameter("@estado", DbType.AnsiStringFixedLength, ven.Estado, 1)) .Add(CreateParameter("@usuCodigo", DbType.AnsiString, ven.UsuCodigo, 10)) End With Try cmd.ExecuteNonQuery() For Each fila As DataRow In detalleTemp.Rows cmd.CommandType = CommandType.StoredProcedure cmd.CommandText = "xspInsertarDetalleVenta" cmd.Parameters.Clear() With cmd.Parameters .Add(CreateParameter("@idVenta", DbType.Int32, dven.IdVenta)) .Add(CreateParameter("@idCliente", DbType.Int32, dven.IdCliente)) .Add(CreateParameter("@idTipoDocumento", DbType.Int32, dven.IdTipoDocumento)) .Add(CreateParameter("@idArticulo", DbType.AnsiString, fila("Código"), 6)) .Add(CreateParameter("@cobraIva", DbType.AnsiStringFixedLength, dven.CobraIva, 1)) .Add(CreateParameter("@cantidad", DbType.Single, fila("Cantidad"))) .Add(CreateParameter("@precio", DbType.Single, fila("Precio"))) .Add(CreateParameter("@subTotal", DbType.Single, fila("Monto"))) End With cmd.ExecuteNonQuery() cmd.CommandText = "xspAfectaDetalleBodegaArticulo" cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Clear() With cmd.Parameters .Add(CreateParameter("@idBodega", DbType.AnsiString, DBArt.IdBodega, 2)) .Add(CreateParameter("@idArticulo", DbType.AnsiString, fila("Código"), 6)) .Add(CreateParameter("@idMovimiento", DbType.Int32, DBArt.IdMovimiento)) .Add(CreateParameter("@cantidad", DbType.Int32, fila("cantidad"))) End With cmd.ExecuteNonQuery() Next cmd.CommandText = "xspAddDetMov" cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Clear() With cmd.Parameters .Add(CreateParameter("@idDetalleMovimiento", DbType.Int32, codDetMov)) .Add(CreateParameter("@idMovimiento", DbType.Int32, codMovi)) .Add(CreateParameter("@usuario", DbType.AnsiString, codUser)) .Add(CreateParameter("@idAfectado", DbType.AnsiString, codAfectado)) End With cmd.ExecuteNonQuery() t.Commit() Catch ex As Exception mensaje = ex.Message t.Rollback() End Try End Using End Sub
Espero te sirva de ayuda.
Pedro Ávila
"El hombre sabio querrá estar siempre con quien sea mejor que él."
Lima - Perú- Editado Pedro Ávila viernes, 27 de mayo de 2016 19:38 ...
-
-
Como te comentaba, no tengo mucha experiencia en la sintaxis de VB, esta documentación te ayudara en el manejo de clases y objetos:
https://msdn.microsoft.com/es-es/library/ms172818%28v=vs.90%29.aspx
y de acuerdo a este, la sintáxis seria:
Dim objeto AS OrdenSV objeto.GuardarOrden(orden)
Hasta Siempre.... Erick Martínez.
-
-
OK, referente al manejo de objetos, ya realice las pruebas y en efecto marca una advertencia, pero es por el ámbito de alcance, si solo dejas el public no hay problema, al final la interacción de clases que realice y funciona es esta:
Creas las clases:
Public Class OrdenSave
Public Sub GuardarOrden(ByVal msg As String)
MessageBox.Show("Accion" + msg)
End Sub
End ClassPublic Class OrdenSV
Public Sub GuardarOrden(ByVal orden As String)
Dim Ors As New OrdenSave
Ors.GuardarOrden(orden)
End Sub
End Class
Después se usa el objeto (Coloque las dos clases a fin de replicar lo que intentas, yo omitiría la clase intermediaria entre la acción y el guardado)
Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim s As New OrdenSV s.GuardarOrden("HOLA!!!!") End Sub End Class
En un formulario coloque un botón y en evento clic coloco las acciones.
*Solo te muestro las interacciones entre objetos, ya colocaras tu código.
Para el almacenar en la BD, el código que muestra Pedro Ávila es lo ideal, solo ajustalo a lo que necesitas.
Como consejo extra, si te has abrumado, despejate 5 minutos. :)
Saludos!
Hasta Siempre.... Erick Martínez.
-
El boton es para guardar una orden de compra.
Te refieres que solo use Public no shared?
He echo los cambios y aun me sale el mismo error desde antes me guardaba el enacabzado y el detalle salio vacio ahora que modifique todo ya no guarda nada pero quizas es por el motivo mismo del detalle algun valor se me queda null que echo el debug y no lo encuentro
Si he visto lo de Pedro pero me confundo mas es diferente a mi codigo usa otras cosas.
JackJJ Piura - Peru
- Editado AcuTau viernes, 27 de mayo de 2016 22:36
-
De hecho no es diferente, solo que se le quita el Shared y se inicializan los objetos, esto es necesario puesto que estas usando Clases.
Es importante que domines esta parte de clases y objetos porque de otra forma no podras avanzar con el guardado de la información en la base de datos.
- Primero se crea una clase.
- En la clase defines tus propiedades, métodos, eventos, constructores, etc.
- Para usar una clase, debes crear un objeto de esa clase, es lo que se denomina inicialización
- Cuando tienes tu objeto ya puedes acceder a las propiedades, métodos, eventos, etc. que hayas creado en esa clase.
Por otro lado esta el tema de los midificadores de acceso (el porque usar o no el Shared), en esta liga esta la documentación que te puede ayudar:
https://msdn.microsoft.com/es-es/library/dd409559.aspx
Hasta Siempre.... Erick Martínez.
-
-
Haciendolo de una forma mas directa me sale error de FK al agregar y a la ves los registre en tabla:
Quizas eso tambien sea el problema anterior el cual no registraba pero no aparecia el error. En otros sistemas que he visto en videos de este tipo de ordenes de servicio no hay tablas relacionadas ?¿ entonces como hacen para relacionar esas dos tablas.
A que se refiere.?
Quitandolo registra el detalle pero no el encabezado, que jodido esto antes era al reves
Ya me desanime seguir con eso.
Gracias a Todos, creo haberlo solucionado. Next Pregunta.
JackJJ Piura - Peru
- Editado AcuTau sábado, 28 de mayo de 2016 16:45
-
Hola, buen día. JackJJ, es un poco tarde la respuesta pero espero si hayas conseguido solucionar tu conflicto. El error de FK que mencionas posiblemente sea a que no hayas creado primero la orden y querias crear el detalle, entonces al no haber una orden primero, se causa el error porque quieres agregar detalles a una orden inexistente.
Saludos.
Hasta Siempre.... Erick Martínez.