All pastes #9v6zvp6MPK Raw Edit

text paste

public text v1 · immutable
#9v6zvp6MPK ·published 2026-09-29 23:53 UTC
rendered paste body
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