Documente Academic
Documente Profesional
Documente Cultură
La consulta es esta:
SELECT * FROM Productos WHERE DATEDIFF(day, GetDate(), FechaVencimiento) <= 10
MessageBox.Show("El producto está a menos de 10 días de vencer")
Que tal amigos, espero me puedan brindar su apoyo para lograr esto.
1.- tengo que registrar en la base de datos notas de adeudo con una fecha limite para
pagarse.
2.- al iniciar el formulario realize una consulta y que en base a ello me muestre con
anticipacion de 3 dias antes por ejemplo de que la nota esta por vencerse y hay que
prevenir el pago.
cnx.Close()
End Sub
el msgbox() solo me muestra que la NOTA1 esta por vencerse. lo que me interesa
saber como le puedo hacer o como debe de ir el codigo para que me muestre que
ambas NOTAS en 2 msgbox seguidos o en un uno solo estan por vencerse.
Respuestas
1
Inicie sesión para votar
Buenas JuanMX.
While dr.Read()
Dim inicio As Date = hoy
Dim final As Date = dr.Item(3)
Dim resultado As TimeSpan = final.Subtract(inicio)
Dim dias As String = resultado.Days.ToString
MsgBox("El Cheque A Nombre De: " + dr.Item(1) + " Por La Cantidad De $ " +
dr.Item(2) + " Pesos " + " Vence En " + dias + " Dias")
Loop
Mostrará un MsgBox por cada usuario.
Comprueba bien la consulta y mira si te he entendido bien.
He tomado en cuenta que trabajabas con SQL Server, para Access se hace así:
DateDiff("d", FechaMaxima, Now())
Dim sql As String = "select * from Cheques WHERE " & _
"(DATEDIFF(day, FechaMaxima, GETDATE()) >= 0) AND " & _
"(DATEDIFF(day, FechaMaxima, GETDATE()) <= 3)"
Muchas veces cuando trabajamos con ABMs o algún proceso de escritura en la base de datos, al actualizar
los registros, debemos establecer si vamos a efectuar un INSERT o un UPDATE. O sea, tenemos que
determinar si el registro existe o no, para saber que operación se va a efectuar en la base de datos.
Generalmente se suele encapsular toda esta lógica dentro de un SP, algo que considero una muy buena
practica, ya que nos desentendemos del lado de la aplicación, si se va a efectuar una operación de inserción
o de modificación.
Primera solución:
Ahora bien, dentro del Store Procedure, lo solemos hacer para determinar la operación, es el famoso IF
EXISTS.
Ejemplo:
IF EXISTS(SELECT ID FROM TABLA WHERE ID = @ID)
INSERT INTO TABLA (Campo1,ID) VALUES (@Valor,@ID)
ELSE
UPDATE TABLA SET Campo1 = @Valor WHERE ID = @ID
No es un mal enfoque, es muy claro. Sin embargo esta solución tiene dos inconvenientes:
1) Estamos pagando el costo de ejecutar un Query. Por mas que la consulta este indexada, tiene un costo.
2) No es 100% segura. En entornos muy demandantes, con alta concurrencia, puede darse el caso de que
justo luego de ejecutar el IF EXISTS, otro proceso inserte en la tabla un registro con la misma PK y no
tendríamos forma de darnos cuenta, generando un error de duplicate key.
Por lo tanto, esta opción que es la más común, tiene serios inconvenientes.
Segunda solución:
Una segunda opción podría ser esta:
En caso, se eliminaría el tener que ejecutar una query con el EXISTS. Aunque en caso de que no exista el
registro, se ejecuta el UPDATE innecesariamente.
Si la mayoría de las operaciones van a ser del tipo INSERT, en realidad no se ganaría performance, pero por
el contrario, si la mayoría de las operaciones seria del tipo UPDATE, podría llegar a ser mas performante.
De todas maneras esta solución sigue teniendo el problema de que otro proceso podría insertar un registro
con la misma PK en la tabla y no tendríamos forma de darnos cuenta.
Tercera solución:
En el segundo caso ganamos un poco de performance (no siempre), pero seguimos con el mismo problema
de concurrencia.
Pero ahora veamos este ejemplo de código:
BEGIN TRY
INSERT INTO TABLA (Campo1,ID) VALUES (@Valor,@ID)
END TRY
BEGIN CATCH
UPDATE TABLA SET Campo1 = @Valor WHERE ID = @ID
END CATCH
A nivel perfomance, es similar a las otras soluciones, pero si tenemos muchas más operaciones de inserción
que de actualización, vamos a ganar velocidad.
Sin embargo, en este caso no tendríamos el inconveniente de concurrencia que sucede en los 2 casos
anteriores!!. Lo cual lo hace ideal para situaciones de alta demanda.
SQL Server 2008, incorpora el comando MERGE (que ya teníamos en Oracle y otros motores), que sirve para
resolver de una manera muy eficiente, exactamente este problema.
MERGE TABLA
USING (SELECT @ID AS ID) AS SRC ON SRC.ID = TABLA.ID
WHEN MATCHED THEN
UPDATE SET Campo1 = @Valor
WHEN NOT MATCHED THEN
INSERT (Campo1,ID) VALUES (@Valor,@ID)
Con este método, también solucionamos el problema de concurrencia, y además evitar tener que ejecutar
consultas innecesarias. Por lo cual, podríamos decir que es la optima solución resolver este problema, aunque
lamentablemente debemos esperar hasta mitad de año, cuando Microsoft libere SQL Server 2008.
Conclusión:
Vimos como un problema en apariencia tonto y trivial, puede causar serios problemas de performance y peor
aun, crear errores de concurrencia y comportamientos no deseados.
Por las pruebas que hicimos en un entorno de TEST, la diferencia de performance que hicimos no son
demasiadas. Pero en situaciones de alta concurrencia, las 2 primeras soluciones son definitivamente
incorrectas.
Recomiendo ver estos links, que explican como funcionan los lockeos, en cada una de las distintas
soluciones:
--------------------------------------...
Dim Consulta As String = "SELECT CodCliente, NombCliente, Imagen FROM
Clientes WHERE NombCliente='" & TextBox1.Text & "'"
Con.Open()
Dim Cadena As SqlDataAdapter = New SqlDataAdapter(Consulta, Con)
Dim Dt As DataTable = New DataTable
Cadena.Fill(Dt)
Yo tengo estas funciones para usar ucListView casi automaticamente (funciona con el
normal y con el mio xD)
En un modulo
Código: Visual Basic
1.
2. Public Sub LV_Preparar(LV As ucListView)
3. Call LV.Initialize
4. Call LV.InitializeImageListHeader
5.
6. Dim i As Integer
7. If LV.ColumnCount > 0 Then
8. For i = LV.ColumnCount To 0 Step -1
9. Call LV.ColumnRemove(i)
10. Next
11. End If
12. End Sub
13.
14. Public Sub LV_Terminar(LV As ucListView)
15. With LV
16. Dim nCol As Integer
17. Dim lCol As Integer
18. lCol = LV.ColumnCount - 1
19. For nCol = 0 To lCol
20. .ColumnIcon(nCol) = -1
21. Next nCol
22.
23. .FullRowSelect = True
24. .GridLines = True
25. .BorderStyle = bsThin
26. .ViewMode = [vmDetails]
27. .RaiseSubItemPrePaint = True ' Para poner efecto
cebra en las filas
28. End With
29. End Sub
30.
31. Public Sub LV_Rellenar(LV As ucListView, rsDatos As
Recordset)
32. LV.Clear
33. Dim itemid As Integer
34. Dim i As Integer
35. Dim nCols As Integer
36. Dim s As String
37. nCols = LV.ColumnCount
38. Dim colLen() As eColumnAutosizeConstants
39. ReDim colLen(nCols)
40. itemid = 0
41. For i = 1 To nCols
42. colLen(i) = caHeader
43. Next
44. If nCols >= rsDatos.Fields.Count Then nCols =
rsDatos.Fields.Count - 1
45. ReDim Preserve colLen(nCols)
46. While Not rsDatos.EOF
47. If IsNull(rsDatos(0)) Then s = "" Else s = rsDatos(0)
48. Call LV.ItemAdd(itemid, rsDatos(0), 0, 0)
49. For i = 1 To nCols
50. If IsNull(rsDatos(i)) Then s = "" Else s =
rsDatos(i)
51. Call LV.SubItemSet(itemid, i, s, 0)
52. If colLen(i) = caHeader Then If Len(s) >
Len(LV.ColumnText(i)) Then colLen(i) = caItem
53. Next
54. rsDatos.MoveNext
55. itemid = itemid + 1
56. Wend
57.
58. For i = 1 To nCols
59. Call LV.ColumnAutosize(i, colLen(i))
60. If colLen(i) = caHeader Then LV.ColumnWidth(i) =
LV.ColumnWidth(i) + 24
61. Next
62. End Sub
63.
64. Public Sub LV_Ajustar(LV As ucListView)
65. Dim i As Integer
66. For i = 1 To LV.ColumnCount - 1
67. Call LV.ColumnAutosize(i, caHeader)
68. Next
69. End Sub
70.
Uso:
Y listo
Curso completo de Visual Basic.Net desde cero, bienvenidos les sugiero a todos los
que se inician a programar aplicaciones Windows Forms que sigan este Tutorial
completo, en este vídeo se detalla el uso del control tooltip para mostrar mensajes
de ayuda en nuestras interfaces en el lenguaje de programación Visual Basic,
crearemos una pequeña aplicación para mostrar mensajes de ayuda en Visual Basic.
www.youtube.com/jcarlosad7
ToolTip
Problema 9:
Crear un programa que permita ingresar de manera obligatoria los nombres, la edad
y el salario de una persona; además todos los campos de texto deben de tener un
mensaje emergente que ayude al usuario final con el contenido que debe ingresar.
Private Sub txtnombres_MouseHover(sender As Object,
e As EventArgs) Handlestxtnombres.MouseHover
ttmensaje.SetToolTip(txtnombres, "Ingrese aquí el nombre del
usuario")
ttmensaje.ToolTipTitle = "Nombre del Usuario"
ttmensaje.ToolTipIcon = ToolTipIcon.Info
End Sub
Private Sub txtedad_MouseHover(sender As Object,
e As EventArgs) Handles txtedad.MouseHover
ttmensaje.SetToolTip(txtedad, "Ingrese aquí la edad del
usuario")
ttmensaje.ToolTipTitle = "Edad del Usuario"
ttmensaje.ToolTipIcon = ToolTipIcon.Info
End Sub
Private Sub txtsalario_MouseHover(sender As Object,
e As EventArgs) Handlestxtsalario.MouseHover
ttmensaje.SetToolTip(txtsalario, "Ingrese aquí el salario del
usuario")
ttmensaje.ToolTipTitle = "Salario del Usuario"
ttmensaje.ToolTipIcon = ToolTipIcon.Info
End Sub
Else
Dim dr As DataRow
dr = ds.Tables("vendedor").Rows(0)
TextBox2.Text = dr("@cod_ven").ToString
TextBox3.Text = dr("@ven_des").ToString
TextBox4.Text = dr("@telefonos").ToString
TextBox5.Text = dr("@direc1").ToString
Fecha_regDateTimePicker.Text = dr("@fecha_reg").ToString
TextBox6.Text = dr("@email").ToString
End If
conex.Close()
Catch ex As Exception
MsgBox(ex.Message)
MsgBox("Datos consultados")
End Try
End Sub