Imports System.Data.SQLitePublic Class Form1 ' Contador global de IDs Private ultimoId As Integer = 0 Private Sub LimpiarCampos() TxtArea.Text = "" TxtCantidad.Text = "" MaskInicio.Text = "" LabelVencimiento.Text = "" End Sub Private Sub AplicarTemaOscuro() For Each fila As DataGridViewRow In dgvCalendario.Rows fila.DefaultCellStyle.BackColor = Color.Black fila.DefaultCellStyle.ForeColor = Color.White Next ' Opcional: también puedes aplicar a los encabezados dgvCalendario.ColumnHeadersDefaultCellStyle.BackColor = Color.Black dgvCalendario.ColumnHeadersDefaultCellStyle.ForeColor = Color.White End Sub Private Function MostrarMensaje(texto As String) As DialogResult Dim frm As New Form2() frm.LabelMensaje.Text = texto frm.BtnCancelar.Visible = False ' Para avisos simples Return frm.ShowDialog() End Function Private Sub MaskInicio_Leave(sender As Object, e As EventArgs) Handles MaskInicio.Leave Dim fechaInicio As Date If DateTime.TryParseExact(MaskInicio.Text, "dd-MM-yyyy", Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.None, fechaInicio) Then ' Calculamos vencimiento: +1 año Dim fechaVencimiento As Date = fechaInicio.AddYears(1) ' Mostramos en el Label LabelVencimiento.Text = fechaVencimiento.ToString("dd-MM-yyyy") Else LabelVencimiento.Text = "" End If End Sub Private Function MostrarMensaje(texto As String, Optional esConfirmacion As Boolean = False) As DialogResult Dim frm As New Form2() frm.LabelMensaje.Text = texto If esConfirmacion Then ' Mostrar con botones Aceptar/Cancelar Return frm.ShowDialog() Else ' Solo mostrar aviso con botón Aceptar frm.BtnCancelar.Visible = False Return frm.ShowDialog() End If End Function Private Function CalcularEstado(fechaVenc As Date) As String Dim diasRestantes As Integer = (fechaVenc.Date - Date.Today).Days If diasRestantes <= 0 Then Return "Vencido" ElseIf diasRestantes <= 14 Then Return "Próximo a vencer" ElseIf diasRestantes <= 21 Then Return "Próximo a vencer" Else Return "Vigente" End If End Function Private Sub ActualizarEstados() For Each fila As DataGridViewRow In dgvCalendario.Rows If fila.Cells("FechaVencimiento").Value IsNot Nothing Then Dim fv As Date If Date.TryParse(fila.Cells("FechaVencimiento").Value.ToString(), fv) Then fila.Cells("Estado").Value = CalcularEstado(fv) End If End If Next End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.KeyPreview = True ' Cargar meses en el ComboBox CmbMeses.Items.Clear() CmbMeses.Items.Add("Seleccionar un Mes") CmbMeses.Items.AddRange(New String() { "01 - Enero", "02 - Febrero", "03 - Marzo", "04 - Abril", "05 - Mayo", "06 - Junio", "07 - Julio", "08 - Agosto", "09 - Septiembre", "10 - Octubre", "11 - Noviembre", "12 - Diciembre"}) CmbMeses.SelectedIndex = 0 ' Configuración inicial del DataGridView With dgvCalendario .ReadOnly = True .AllowUserToAddRows = False .AllowUserToDeleteRows = False .AllowUserToResizeColumns = False .AllowUserToResizeRows = False .SelectionMode = DataGridViewSelectionMode.CellSelect .RowHeadersVisible = False .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill .ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing .ColumnHeadersHeight = 35 .EnableHeadersVisualStyles = False .ColumnHeadersDefaultCellStyle.BackColor = Color.DarkSlateGray .ColumnHeadersDefaultCellStyle.ForeColor = Color.White .ColumnHeadersDefaultCellStyle.Font = New Font("Segoe UI", 9, FontStyle.Bold) .ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter .ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.True .BackgroundColor = Color.Black .GridColor = Color.Silver .RowsDefaultCellStyle.BackColor = Color.Black .RowsDefaultCellStyle.ForeColor = Color.White .AlternatingRowsDefaultCellStyle.BackColor = Color.Black .AlternatingRowsDefaultCellStyle.ForeColor = Color.White .DefaultCellStyle.SelectionBackColor = Color.DarkRed .DefaultCellStyle.SelectionForeColor = Color.White .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter .RowTemplate.Height = 30 End With CrearTablaSiNoExiste() ' 🔹 Recargar datos y aplicar lógica completa CargarDatos() ActualizarEstados() ActualizarResumen() ' Configuración inicial del MaskedTextBox MaskInicio.Text = "" MaskInicio.BackColor = Color.Black MaskInicio.ForeColor = Color.White End Sub Private Sub BtnConsultar_Click(sender As Object, e As EventArgs) Handles BtnConsultar.Click If CmbMeses.SelectedIndex = -1 OrElse CmbMeses.Text = "Seleccionar un Mes" Then MostrarMensaje("Debe seleccionar un mes antes de consultar.") Return End If ' Extraer el número de mes desde el texto (ej: "05 - Mayo" → "05") Dim mesSeleccionado As String = CmbMeses.Text.Substring(0, 2) Using conn As New SQLiteConnection("Data Source=extintores.db;Version=3;") conn.Open() Dim sql As String = "SELECT Id, Area, Cantidad, FechaInicio, FechaVencimiento, Estado FROM Extintores WHERE strftime('%m', FechaVencimiento) = @Mes ORDER BY FechaVencimiento ASC" Using cmd As New SQLiteCommand(sql, conn) cmd.Parameters.AddWithValue("@Mes", mesSeleccionado) Dim da As New SQLiteDataAdapter(cmd) Dim dt As New DataTable() da.Fill(dt) dgvCalendario.DataSource = dt End Using End Using ' Recalcular estado en tiempo real según la fecha de vencimiento For Each fila As DataGridViewRow In dgvCalendario.Rows If fila.Cells("FechaVencimiento").Value IsNot Nothing Then Dim fv As Date If Date.TryParse(fila.Cells("FechaVencimiento").Value.ToString(), fv) Then Dim diasRestantes As Integer = (fv.Date - Date.Today).Days Dim estado As String If diasRestantes <= 0 Then estado = "Vencido" ElseIf diasRestantes <= 14 Then estado = "Próximo a vencer" ElseIf diasRestantes <= 21 Then estado = "Próximo a vencer" Else estado = "Vigente" End If fila.Cells("Estado").Value = estado End If End If ' Formatear fechas en dd-MM-yyyy If fila.Cells("FechaInicio").Value IsNot Nothing Then Dim fi As Date If Date.TryParse(fila.Cells("FechaInicio").Value.ToString(), fi) Then fila.Cells("FechaInicio").Value = fi.ToString("dd-MM-yyyy") End If End If If fila.Cells("FechaVencimiento").Value IsNot Nothing Then Dim fv As Date If Date.TryParse(fila.Cells("FechaVencimiento").Value.ToString(), fv) Then fila.Cells("FechaVencimiento").Value = fv.ToString("dd-MM-yyyy") End If End If Next ResetearComboMeses() End Sub Private Sub ResetearComboMeses() CmbMeses.SelectedIndex = -1 CmbMeses.Text = "Seleccionar un Mes" End Sub Private Sub BtnEliminar_Click(sender As Object, e As EventArgs) Handles BtnEliminar.Click If dgvCalendario.CurrentRow IsNot Nothing Then Dim id As Integer = Convert.ToInt32(dgvCalendario.CurrentRow.Cells("Id").Value) ' Preguntar confirmación en Form2 Dim frmConfirmar As New Form2() frmConfirmar.LabelMensaje.Text = "¿Está seguro de eliminar el extintor seleccionado?" frmConfirmar.BtnAceptar.Text = "Aceptar" frmConfirmar.BtnCancelar.Text = "Cancelar" ' Configurar eventos para BCEvoButton AddHandler frmConfirmar.BtnAceptar.Click, Sub() frmConfirmar.Tag = "OK" frmConfirmar.Close() End Sub AddHandler frmConfirmar.BtnCancelar.Click, Sub() frmConfirmar.Tag = "Cancel" frmConfirmar.Close() End Sub frmConfirmar.ShowDialog() If frmConfirmar.Tag IsNot Nothing AndAlso frmConfirmar.Tag.ToString() = "OK" Then ' Borrar en la base de datos Using conn As New SQLite.SQLiteConnection("Data Source=extintores.db;Version=3;") conn.Open() Dim sql As String = "DELETE FROM Extintores WHERE Id=@Id" Using cmd As New SQLite.SQLiteCommand(sql, conn) cmd.Parameters.AddWithValue("@Id", id) cmd.ExecuteNonQuery() End Using End Using ' Recargar datos en vez de remover manualmente CargarDatos() ' Aviso de confirmación Dim aviso As New Form2() aviso.LabelMensaje.Text = "Registro eliminado correctamente." aviso.ShowDialog() ElseIf frmConfirmar.Tag IsNot Nothing AndAlso frmConfirmar.Tag.ToString() = "Cancel" Then ' Aviso de cancelación Dim aviso As New Form2() aviso.LabelMensaje.Text = "Eliminación cancelada por el usuario." aviso.ShowDialog() End If Else Dim aviso As New Form2() aviso.LabelMensaje.Text = "Seleccione una fila para eliminar." aviso.ShowDialog() End If ActualizarEstados() ActualizarResumen() End Sub Private Sub BtnTodos_Click(sender As Object, e As EventArgs) Handles BtnTodos.Click CargarDatos() ActualizarEstados() End Sub Private Sub BtnEditar_Click(sender As Object, e As EventArgs) Handles BtnEditar.Click If dgvCalendario.CurrentRow IsNot Nothing Then Dim fila As DataGridViewRow = dgvCalendario.CurrentRow Dim formEdit As New FormEditar() ' Pasar valores actuales formEdit.TxtArea.Text = fila.Cells("Area").Value.ToString() formEdit.TxtCantidad.Text = fila.Cells("Cantidad").Value.ToString() formEdit.MaskInicio.Text = fila.Cells("FechaInicio").Value.ToString() ' Preguntar confirmación en Form2 antes de editar Dim frmConfirmar As New Form2() frmConfirmar.LabelMensaje.Text = "¿Está seguro de editar el extintor seleccionado?" frmConfirmar.BtnAceptar.Text = "Aceptar" frmConfirmar.BtnCancelar.Text = "Cancelar" AddHandler frmConfirmar.BtnAceptar.Click, Sub() frmConfirmar.Tag = "OK" frmConfirmar.Close() End Sub AddHandler frmConfirmar.BtnCancelar.Click, Sub() frmConfirmar.Tag = "Cancel" frmConfirmar.Close() End Sub frmConfirmar.ShowDialog() If frmConfirmar.Tag IsNot Nothing AndAlso frmConfirmar.Tag.ToString() = "OK" Then ' Mostrar formulario de edición If formEdit.ShowDialog() = DialogResult.OK Then ' Actualizar valores en la grilla fila.Cells("Area").Value = formEdit.TxtArea.Text fila.Cells("Cantidad").Value = formEdit.TxtCantidad.Text fila.Cells("FechaInicio").Value = formEdit.MaskInicio.Text fila.Cells("FechaVencimiento").Value = formEdit.FechaVencimientoCalculada ' Recalcular estado Dim fechaVenc As Date = Date.Parse(fila.Cells("FechaVencimiento").Value.ToString()) fila.Cells("Estado").Value = CalcularEstado(fechaVenc) ' Guardar en la base de datos (UPDATE) Dim id As Integer = Convert.ToInt32(fila.Cells("Id").Value) Using conn As New SQLite.SQLiteConnection("Data Source=extintores.db;Version=3;") conn.Open() Dim sql As String = "UPDATE Extintores SET Area=@Area, Cantidad=@Cantidad, FechaInicio=@FechaInicio, FechaVencimiento=@FechaVencimiento, Estado=@Estado WHERE Id=@Id" Using cmd As New SQLite.SQLiteCommand(sql, conn) cmd.Parameters.AddWithValue("@Area", formEdit.TxtArea.Text) cmd.Parameters.AddWithValue("@Cantidad", Convert.ToInt32(formEdit.TxtCantidad.Text)) cmd.Parameters.AddWithValue("@FechaInicio", Date.Parse(formEdit.MaskInicio.Text).ToString("yyyy-MM-dd")) cmd.Parameters.AddWithValue("@FechaVencimiento", Date.Parse(formEdit.FechaVencimientoCalculada).ToString("yyyy-MM-dd")) cmd.Parameters.AddWithValue("@Estado", fila.Cells("Estado").Value.ToString()) cmd.Parameters.AddWithValue("@Id", id) cmd.ExecuteNonQuery() End Using End Using ' Aviso de confirmación Dim aviso As New Form2() aviso.LabelMensaje.Text = "Registro editado correctamente." aviso.ShowDialog() End If ElseIf frmConfirmar.Tag IsNot Nothing AndAlso frmConfirmar.Tag.ToString() = "Cancel" Then ' Aviso de cancelación Dim aviso As New Form2() aviso.LabelMensaje.Text = "Edición cancelada por el usuario." aviso.ShowDialog() End If Else ' Aviso de confirmación Dim aviso As New Form2() aviso.LabelMensaje.Text = "Registro editado correctamente." aviso.ShowDialog() End If ' 🔹 Recargar datos ordenados y refrescar estados CargarDatos() ActualizarEstados() ActualizarResumen() End Sub Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown If e.KeyCode = Keys.Escape Then dgvCalendario.ClearSelection() dgvCalendario.CurrentCell = Nothing For Each fila As DataGridViewRow In dgvCalendario.Rows fila.DefaultCellStyle.BackColor = Color.Black fila.DefaultCellStyle.ForeColor = Color.White Next End If End Sub ' --- TimerAviso --- Private avisadosHoy As New HashSet(Of Integer) Private fechaUltimoAviso As Date = Date.Today Private Sub TimerAviso_Tick(sender As Object, e As EventArgs) Handles TimerAviso.Tick Dim horaActual As Integer = DateTime.Now.Hour ' Reiniciar lista de avisados cada día If fechaUltimoAviso <> Date.Today Then avisadosHoy.Clear() fechaUltimoAviso = Date.Today End If ' Solo entre 8 y 17 horas If horaActual >= 8 AndAlso horaActual <= 22 Then Using conn As New SQLiteConnection("Data Source=extintores.db;Version=3;") conn.Open() ' Buscar extintores que vencen en los próximos 21 días o ya vencidos Dim cmd As New SQLiteCommand("SELECT Id, Area, FechaVencimiento FROM Extintores WHERE date(FechaVencimiento) <= date('now', '+21 days') ORDER BY FechaVencimiento ASC", conn) Dim reader As SQLiteDataReader = cmd.ExecuteReader() Dim listaAvisos As New Text.StringBuilder() While reader.Read() Dim id As Integer = Convert.ToInt32(reader("Id")) Dim area As String = reader("Area").ToString() Dim fechaVenc As Date = Date.Parse(reader("FechaVencimiento").ToString()) Dim diasRestantes As Integer = (fechaVenc.Date - Date.Today).Days ' Solo incluir si no fue avisado hoy If Not avisadosHoy.Contains(id) Then If diasRestantes < 0 Then listaAvisos.AppendLine("• Extintor en área " & area & " venció el " & fechaVenc.ToString("dd-MM-yyyy") & " (vencido hace " & Math.Abs(diasRestantes) & " días)") Else listaAvisos.AppendLine("• Extintor en área " & area & " vence el " & fechaVenc.ToString("dd-MM-yyyy") & " (faltan " & diasRestantes & " días)") End If avisadosHoy.Add(id) End If End While reader.Close() ' Mostrar un solo aviso si hay registros If listaAvisos.Length > 0 Then Dim frmAviso As New Form2() frmAviso.LabelMensaje.Text = "Extintores próximos a vencer:" & vbCrLf & vbCrLf & listaAvisos.ToString() frmAviso.ShowDialog() End If End Using End If End Sub Private Sub ActualizarResumen() Dim sqlResumen As String = "SELECT Estado, COUNT(*) AS Cantidad FROM Extintores GROUP BY Estado" Dim totalGeneral As Integer = 0 Using conn As New SQLiteConnection("Data Source=extintores.db;Version=3;") conn.Open() Using cmdTotal As New SQLiteCommand("SELECT COUNT(*) FROM Extintores", conn) totalGeneral = Convert.ToInt32(cmdTotal.ExecuteScalar()) End Using Using cmd As New SQLiteCommand(sqlResumen, conn) Using reader As SQLiteDataReader = cmd.ExecuteReader() While reader.Read() Dim estado As String = reader("Estado").ToString() Dim cantidad As Integer = Convert.ToInt32(reader("Cantidad")) Select Case estado Case "Vigente" lblVigente.Text = "Vigentes: " & cantidad Case "Próximo a vencer" lblProximo.Text = "Próximos: " & cantidad Case "Vencido" lblVencido.Text = "Vencidos: " & cantidad End Select End While End Using End Using End Using lblTotal.Text = "Total: " & totalGeneral End Sub Private Sub CrearTablaSiNoExiste() Using conn As New SQLiteConnection("Data Source=extintores.db;Version=3;") conn.Open() Dim sql As String = "CREATE TABLE IF NOT EXISTS Extintores (" & "Id INTEGER PRIMARY KEY AUTOINCREMENT," & "Area TEXT," & "Cantidad INTEGER," & "FechaInicio TEXT," & "FechaVencimiento TEXT," & "Estado TEXT)" Dim cmd As New SQLiteCommand(sql, conn) cmd.ExecuteNonQuery() End Using End Sub Private Sub CargarDatos() Using conn As New SQLiteConnection("Data Source=extintores.db;Version=3;") conn.Open() Dim sql As String = "SELECT Id, Area, Cantidad, FechaInicio, FechaVencimiento, Estado FROM Extintores ORDER BY FechaVencimiento ASC;" Using cmd As New SQLiteCommand(sql, conn) Dim da As New SQLiteDataAdapter(cmd) Dim dt As New DataTable() da.Fill(dt) dgvCalendario.DataSource = dt End Using End Using ' Quitar flecha negra de ordenamiento For Each col As DataGridViewColumn In dgvCalendario.Columns col.SortMode = DataGridViewColumnSortMode.NotSortable col.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter Next ' Encabezados en dos líneas dgvCalendario.Columns("FechaVencimiento").HeaderText = "Fecha" & vbCrLf & "Vencimiento" dgvCalendario.Columns("FechaInicio").HeaderText = "Fecha" & vbCrLf & "Inicio" dgvCalendario.Columns("Cantidad").HeaderText = "Cantidad Extintor" ' Formato de fechas For Each fila As DataGridViewRow In dgvCalendario.Rows If fila.Cells("FechaInicio").Value IsNot Nothing Then Dim fi As Date If Date.TryParse(fila.Cells("FechaInicio").Value.ToString(), fi) Then fila.Cells("FechaInicio").Value = fi.ToString("dd-MM-yyyy") End If End If If fila.Cells("FechaVencimiento").Value IsNot Nothing Then Dim fv As Date If Date.TryParse(fila.Cells("FechaVencimiento").Value.ToString(), fv) Then fila.Cells("FechaVencimiento").Value = fv.ToString("dd-MM-yyyy") End If End If Next ' 🔹 Fijar ancho de columnas (ajusta valores según tu preferencia) If dgvCalendario.Columns.Contains("Id") Then dgvCalendario.Columns("Id").Width = 50 End If If dgvCalendario.Columns.Contains("Area") Then dgvCalendario.Columns("Area").Width = 120 End If If dgvCalendario.Columns.Contains("Cantidad") Then dgvCalendario.Columns("Cantidad").Width = 90 End If If dgvCalendario.Columns.Contains("FechaInicio") Then dgvCalendario.Columns("FechaInicio").Width = 110 End If If dgvCalendario.Columns.Contains("FechaVencimiento") Then dgvCalendario.Columns("FechaVencimiento").Width = 120 End If If dgvCalendario.Columns.Contains("Estado") Then dgvCalendario.Columns("Estado").Width = 120 End If End Sub Private Sub ResetearIds(tabla As String) Try Using conn As New SQLiteConnection("Data Source=extintores.db;Version=3;") conn.Open() ' Verificar si la tabla tiene registros Dim sqlCount As String = $"SELECT COUNT(*) FROM {tabla}" Using cmdCount As New SQLiteCommand(sqlCount, conn) Dim totalRegistros As Integer = Convert.ToInt32(cmdCount.ExecuteScalar()) If totalRegistros > 0 Then ' Mostrar aviso en Form2 Dim frmMsg As New Form2() frmMsg.LabelMensaje.Text = "⚠️ No se puede resetear el ID mientras existan registros. Elimine todos los datos primero." frmMsg.ShowDialog() Exit Sub End If End Using ' Si está vacía, resetear el autoincremento Dim sqlReset As String = "DELETE FROM sqlite_sequence WHERE name=@tabla;" Using cmdReset As New SQLiteCommand(sqlReset, conn) cmdReset.Parameters.AddWithValue("@tabla", tabla) cmdReset.ExecuteNonQuery() End Using End Using ' Mostrar mensaje en Form2 Dim frmMsgOk As New Form2() frmMsgOk.LabelMensaje.Text = "✅ El contador de IDs de la tabla '" & tabla & "' fue reseteado correctamente. El próximo registro comenzará desde 1." frmMsgOk.ShowDialog() Catch ex As Exception ' Mostrar error en Form2 Dim frmMsgErr As New Form2() frmMsgErr.LabelMensaje.Text = "Error al resetear IDs: " & ex.Message frmMsgErr.ShowDialog() End Try End Sub Private Sub BtnResetear_Click(sender As Object, e As EventArgs) Handles BtnResetear.Click ResetearIds("Extintores") End Sub Private Sub DgvCalendario_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles dgvCalendario.CellFormatting If dgvCalendario.Columns(e.ColumnIndex).Name = "FechaVencimiento" AndAlso e.Value IsNot Nothing Then Dim fechaVenc As Date = Date.Parse(e.Value.ToString()) Dim diasRestantes As Integer = (fechaVenc.Date - DateTime.Today).Days If diasRestantes <= 0 Then ' Vencido → rojo e.CellStyle.BackColor = Color.DarkRed e.CellStyle.ForeColor = Color.White e.CellStyle.SelectionBackColor = Color.DarkRed e.CellStyle.SelectionForeColor = Color.White ElseIf diasRestantes <= 21 Then ' Próximo a vencer → amarillo e.CellStyle.BackColor = Color.Yellow e.CellStyle.ForeColor = Color.Black e.CellStyle.SelectionBackColor = Color.Goldenrod e.CellStyle.SelectionForeColor = Color.Black ElseIf diasRestantes <= 21 Then ' Próximo a vencer → tema oscuro normal (negro) e.CellStyle.BackColor = Color.Black e.CellStyle.ForeColor = Color.White e.CellStyle.SelectionBackColor = Color.Black e.CellStyle.SelectionForeColor = Color.White Else ' Vigente → tema oscuro normal e.CellStyle.BackColor = Color.Black e.CellStyle.ForeColor = Color.White e.CellStyle.SelectionBackColor = Color.Black e.CellStyle.SelectionForeColor = Color.White End If End If End Sub ' --- ToolTip dinámico en Estado y FechaVencimiento --- Private Sub dgvCalendario_CellToolTipTextNeeded(sender As Object, e As DataGridViewCellToolTipTextNeededEventArgs) Handles dgvCalendario.CellToolTipTextNeeded If e.RowIndex >= 0 AndAlso e.ColumnIndex >= 0 Then Dim colName As String = dgvCalendario.Columns(e.ColumnIndex).Name If colName = "Estado" OrElse colName = "FechaVencimiento" Then Dim fila As DataGridViewRow = dgvCalendario.Rows(e.RowIndex) If fila.Cells("FechaVencimiento").Value IsNot Nothing Then Dim fv As Date If Date.TryParse(fila.Cells("FechaVencimiento").Value.ToString(), fv) Then Dim diasRestantes As Integer = (fv - Date.Today).Days If diasRestantes < 0 Then e.ToolTipText = $"Vencido hace {Math.Abs(diasRestantes)} días" ElseIf diasRestantes <= 14 Then e.ToolTipText = $"Faltan {diasRestantes} días (Próximo a vencer - amarillo)" ElseIf diasRestantes <= 21 Then e.ToolTipText = $"Faltan {diasRestantes} días (Próximo a vencer)" Else e.ToolTipText = $"Faltan {diasRestantes} días (Vigente)" End If End If End If End If End If End Sub ' --- Botón Agregar (nuevo o edición) --- Private Sub BtnAgregar_Click(sender As Object, e As EventArgs) Handles BtnAgregar.Click ' Validar campos obligatorios If String.IsNullOrWhiteSpace(TxtArea.Text) OrElse String.IsNullOrWhiteSpace(TxtCantidad.Text) Then MostrarMensaje("Debe ingresar Área y Cantidad.") Return End If ' Validar fecha de inicio Dim fechaInicio As Date If Not DateTime.TryParseExact(MaskInicio.Text, "dd-MM-yyyy", Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.None, fechaInicio) Then MostrarMensaje("Ingrese una fecha válida en formato dd-MM-yyyy.") Return End If ' Calcular vencimiento (+1 año) Dim fechaVencimiento As Date = fechaInicio.AddYears(1) LabelVencimiento.Text = fechaVencimiento.ToString("dd-MM-yyyy") ' Calcular estado Dim diasRestantes As Integer = (fechaVencimiento.Date - Date.Today).Days Dim estado As String If diasRestantes <= 0 Then estado = "Vencido" ElseIf diasRestantes <= 14 Then estado = "Próximo a vencer" ElseIf diasRestantes <= 21 Then estado = "Próximo a vencer" Else estado = "Vigente" End If ' Guardar en SQLite Using conn As New SQLiteConnection("Data Source=extintores.db;Version=3;") conn.Open() If BtnAgregar.Tag IsNot Nothing Then ' Modo edición Dim idEditar As Integer = CInt(BtnAgregar.Tag) Dim sqlUpdate As String = "UPDATE Extintores SET Area=@Area, Cantidad=@Cantidad, FechaInicio=@FechaInicio, FechaVencimiento=@FechaVencimiento, Estado=@Estado WHERE Id=@Id" Using cmd As New SQLiteCommand(sqlUpdate, conn) cmd.Parameters.AddWithValue("@Area", TxtArea.Text) cmd.Parameters.AddWithValue("@Cantidad", Convert.ToInt32(TxtCantidad.Text)) cmd.Parameters.AddWithValue("@FechaInicio", fechaInicio.ToString("yyyy-MM-dd")) cmd.Parameters.AddWithValue("@FechaVencimiento", fechaVencimiento.ToString("yyyy-MM-dd")) cmd.Parameters.AddWithValue("@Estado", estado) cmd.Parameters.AddWithValue("@Id", idEditar) cmd.ExecuteNonQuery() End Using BtnAgregar.Tag = Nothing Else ' Nuevo registro Dim sqlInsert As String = "INSERT INTO Extintores (Area, Cantidad, FechaInicio, FechaVencimiento, Estado) VALUES (@Area, @Cantidad, @FechaInicio, @FechaVencimiento, @Estado)" Using cmd As New SQLiteCommand(sqlInsert, conn) cmd.Parameters.AddWithValue("@Area", TxtArea.Text) cmd.Parameters.AddWithValue("@Cantidad", Convert.ToInt32(TxtCantidad.Text)) cmd.Parameters.AddWithValue("@FechaInicio", fechaInicio.ToString("yyyy-MM-dd")) cmd.Parameters.AddWithValue("@FechaVencimiento", fechaVencimiento.ToString("yyyy-MM-dd")) cmd.Parameters.AddWithValue("@Estado", estado) cmd.ExecuteNonQuery() End Using End If End Using ' Recargar datos y actualizar resumen CargarDatos() ActualizarResumen() LimpiarCampos() ' Aviso Dim aviso As New Form2() aviso.LabelMensaje.Text = "Registro guardado correctamente." aviso.ShowDialog() End Sub Private Sub BtnDB_Click(sender As Object, e As EventArgs) Handles BtnDB.Click ' Confirmación en Form2 Dim frmConfirmar As New Form2() frmConfirmar.LabelMensaje.Text = "¿Está seguro de eliminar TODOS los registros de la base de datos?" frmConfirmar.BtnAceptar.Text = "Aceptar" frmConfirmar.BtnCancelar.Text = "Cancelar" AddHandler frmConfirmar.BtnAceptar.Click, Sub() frmConfirmar.Tag = "OK" frmConfirmar.Close() End Sub AddHandler frmConfirmar.BtnCancelar.Click, Sub() frmConfirmar.Tag = "Cancel" frmConfirmar.Close() End Sub frmConfirmar.ShowDialog() If frmConfirmar.Tag IsNot Nothing AndAlso frmConfirmar.Tag.ToString() = "OK" Then Using conn As New SQLite.SQLiteConnection("Data Source=extintores.db;Version=3;") conn.Open() ' 🔹 Eliminar todos los registros de la tabla Dim sql As String = "DELETE FROM Extintores" Using cmd As New SQLite.SQLiteCommand(sql, conn) cmd.ExecuteNonQuery() End Using End Using ' Recargar grilla y resumen CargarDatos() ActualizarEstados() ActualizarResumen() ' Aviso Dim aviso As New Form2() aviso.LabelMensaje.Text = "Todos los registros fueron eliminados." aviso.ShowDialog() Else Dim aviso As New Form2() aviso.LabelMensaje.Text = "Eliminación cancelada por el usuario." aviso.ShowDialog() End If End SubEnd Class