Problema con un Userform y la función SelectionChange en Excel

Al momento de abrir la hoja de excel, me abre el userForm, introduzco los datos y le doy al botón capturar, al final de ejecución del botón coloque "End" y me cierra la ventana dejándome usar la hoja de excel, hay tengo que introducir datos con ayuda de un selectionChange con el cual pretendo que cada cambio que realice, se ejecute el código hay puesto, el detalle esta en que cuando cierro la ventana del UserForm todas mis variables me las manda a 0 y si las meto dentro del selectionChange me carga una y otra vez el mismo valor en la variable declarada, use un select case para evitar esto y que solo le de los valores una sola vez, el detalle es que no me respeta el select case y aunque la variable que uso para evaluar en el Select case sea 1 siempre entra a todos los demás casos, además de que se me hace un bucle infinito en una función de copiar y pegar,¿habrá alguna manera de que pueda declarar mis variables al cerrar el userform?

1 respuesta

Respuesta
1

H o l a : Te explico un poco sobre el manejo de variables.

El userform se carga en memoria, cuando cierras el userform, todo el contenido del userform se destruye, es decir, no queda nada en memoria. Se puede resolver de esta forma, antes de cerrar el userform, pasas los datos a unas celdas en una hoja temporal. De esa forma, puedes leer los valores de la hoja temporal y ocuparlos en tu hoja.

Otra forma de utilizar las variables es, antes de abrir el userform, declaras variables públicas; antes de cerrar el userform actualizas las variables públicas, de esa forma cuando cierres el userform, los valores quedarán en las variables públicas.

Te recomiendo la primera opción.


Para resolver los problemas en tu hoja con el evento SelectionChange, podrías poner el código y una explicación del resultado deseado.


O bien, explícame todo lo que quieres hacer y te ayudo con la solución completa.

Private Sub ReStart_Click()

Range("C3").ClearContents
Range("D3:E3").ClearContents
Range("F3").ClearContents
Range("B8:G2000").Clear
Range("C7:D7").ClearContents
Range("F7").ClearContents
Range("B7").Value = 1
SelectCase = 0
NumberColumn = "C"
NumberRow = 7
FrmWindow.Show

End Sub

Aqui tengo que al precionar un boton en la hoja de excel que me abre el userform (FrmWindow.Show), las celdas que menciono son donde guardo los datos que coloco en el userform al momento de presionar capturar

Range("C3").FormulaR1C1 = Model
Range("D3").FormulaR1C1 = Batch
Range("F3").FormulaR1C1 = TotalPieces
TotalBox = (TotalPieces / SalesCarton)
Range("E4").FormulaR1C1 = TotalBox
Range("E5").FormulaR1C1 = SalesCarton
Model = Range("C3").Value
Range("C7").Select
End

aqui es donde me guarda los valores en las celdas despues al momento de escanear un dato me introduce el valor en una celda y tengo el SelectionCange para que realice la funcion que le programe donde kiero que realice una copia de un renglon y lo copee debajo igual y le limpe el contenido y asi sucecivamente por 10 veces el detalle es que se regresa hasta el primer renglon y hace la comparacion de cada renglon cuando solo quiero que haga la comparacion del ultimo

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Select Case (SelectCase)
Case 0
NumberColumn = "C"
NumberRow = 7
NumberCell = NumberColumn & NumberRow
Range(NumberCell).Select
NumberColumnA = "B"
NumberColumnB = "G"
Batch = Range("D3").Value
TotalPieces = Range("F3").Value
TotalBox = Range("E4").Value
SalesCarton = Range("E5").Value
SalesCarton = SalesCarton + 1
CounterPouch = 1
CounterBox = 0
SelectCase = 1
Counter = 1
End Select
Select Case (SelectCase)
Case 1
If (CounterBox = TotalBox) Then
Range("F4").Select
Selection.ClearContents
Range("F4").Select
End
Else
CodePouch = ""
BatchLabel = ""
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
If (Range(NumberCell).Value = "") Then
CodePouch = ""
BatchLabel = ""
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
Else
If (Counter = SalesCarton) Then ' Sales Carton Pouch Scanning
CodeBox = Left(Range(NumberCell).Value, 4)
If (CodeBox = "0110") Then
BatchLabel = Right(Range(NumberCell).Value, 10)
If (BatchLabel = Batch) Then
CounterBox = CounterBox + 1
Counter = 1
NumberColumn = "G"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Value = "PASA"
Range(Cells(NumberRow, NumberColumnA), Cells(NumberRow, NumberColumnB)).Copy
NumberRow = (NumberRow + 1)
NumberColumn = "B"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
Selection.PasteSpecial
Selection.ClearContents
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
Selection.Value = CounterPouch
NumberColumn = "C"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
CodePouch = ""
BatchLabel = ""
End
Else
NumberColumn = "G"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Value = "NO PASA"
NumberColumn = "F"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
MsgBox "Codigo Incorrecto", vbCritical
CodePouch = ""
BatchLabel = ""
End
End If
Else
If (Range(NumberCell).Value <> "") Then
NumberColumn = "G"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Value = "NO PASA"
NumberColumn = "F"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
MsgBox "Etiqueta Erronea", vbCritical
CodePouch = ""
BatchLabel = ""
End
Else
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
End If
End If
Else ' Label Pouch Scanning
CodePouch = Left(Range(NumberCell).Value, 4)
If (CodePouch = "0100") Then
BatchLabel = Right(Range(NumberCell).Value, 10)
If (BatchLabel = Batch) Then
Counter = Counter + 1
CounterPouch = CounterPouch + 1
NumberColumn = "D"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Value = "PASA"
If (Counter < SalesCarton) Then
Range(Cells(NumberRow, NumberColumnA), Cells(NumberRow, NumberColumnB)).Copy
NumberRow = (NumberRow + 1)
NumberColumn = "B"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
Selection.PasteSpecial
Selection.ClearContents
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
Selection.Value = CounterPouch
NumberColumn = "C"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
CodePouch = ""
BatchLabel = ""
End
Else
NumberColumn = "F"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
End
End If
Else
NumberColumn = "D"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Value = "NO PASA"
NumberColumn = "C"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
MsgBox "Codigo Incorrecto", vbCritical
CodePouch = ""
BatchLabel = ""
End
End If
Else
If (Range(NumberCell).Value <> "") Then
NumberColumn = "D"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Value = "NO PASA"
NumberColumn = "C"
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
MsgBox "Etiqueta Erronea", vbCritical
CodePouch = ""
BatchLabel = ""
End
Else
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
End
End If
End If
End If
NumberCell = (NumberColumn & NumberRow)
Range(NumberCell).Select
End If
End If
End Select
End Sub

No entendí lo que necesitas.

Mejor explícame con detalle lo que quieres hacer y te hago la solución completa.

Bueno el primer paso es introducir con un escáner de código de barras el valor a un costado de la celda que dice 1 donde dice "Pouch"

Luego de este código cargado te extrae los primeros 4 dígitos si el código comienza con "0100" pasa a extraer los últimos 10 si los últimos 10 son iguales a donde dice "NO LOTE (F11624504D)" si se cumplen estas 2 condiciones donde dice "ESTATUS" se pondrá de color verde y dirá "PASA" copiara el renglón en la parte de abajo y en numero de parte colocara el que sige "2" y borrara el contenido las demás para dejarlas en blanco,

y asi susecivamente

Si las condiciones anteriores no se cumplen te manda una alerta de etiqueta equivocada y sale un MsgBox y volverá a la misma celda para que escanees una correcta

Al llegar a 10 etiquetas te pedirá escanear una etiqueta de "SALES CARTÓN" y aplica la misma condición solo que en lugar de ser "0100" sera "0110"

En mi userform tu cargas los valores que aparecen arriba "MODELO", "NO LOTE" y "CANTIDAD DE LOTE" además te pide que introduzcas cuantas etiquetas escanearas antes de que escanees un de sales cartón pueden ser 5, 10, 25, o algún numero "X" en este caso estoy usando la opción de 10

El Userform funciona a la perfección y todos los valores los captura en celdas de la hoja para yo después jalarlos cuando los necesite, estas funciones las logro mediante la función de SelectionChange donde le coloque una condición de que si yo doy click en cualquier otra zona automáticamente se selecciona la misma celda, algo así como un bloqueo contra escritura y modificaciones, siempre se seleccionara la celda donde debes introducir el código de las etiquetas, el problema es que cuando introduces un nuevo código de etiqueta el programa comienza a evaluar desde la etiqueta numero 1 y se va de uno en uno hasta llegar a la etiqueta en la voy y cuando hace eso, el programa se cuatrapea y se limita solo hasta la numero 28 y de ahí ya no sigue su función normal, lo que quiero evitar es que se reinicie la verificación desde la etiqueta numero 1

Al inicio de tu macro tienes esto:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Select Case (SelectCase)

Pero si la variable "SelectCase" no es pública, siempre será vacío.

Si ya estás utilizando un userform, por qué no capturas el código en un textbox, realizas las validaciones necesarias; y si está bien, entonces lo pasas a la hoja.


Te explico el funcionamiento del evento SelectionChange, cada vez que seleccionas una celda, se activa el evento, es por eso que entra en un bucle.

Por ejemplo, en tu macro tienes esto:

Range("F4").Select
Selection. ClearContents
Range("F4").Select

Entonces cuando pones Range("F4"). Select, el evento se activa y vuelve a iniciar desde el principio, es decir desde esta parte:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Select Case (SelectCase)

Cuando pones el siguiente Range("F4"). Select, el evento se activa nuevamente, y es por eso que en algún momento la memoria se satura y excel se bloquea.


Una opción es que desactives los eventos al inicio de tu macro y los vuelvas a activar antes de salir de la macro.

La instrucción para desactivar los eventos es :

Application.EnableEvents = False

Y para activar:

Application.EnableEvents = True


Prueba y me comentas. Si no es lo que necesitas, podemos rediseñar tu modelo de captura.

Una opción es que captures el código en el userform y lo pases a la hoja, con esto no utilizaremos el evento SelectionChange.

Otra opción es capturar directamente en la hoja. Pero habría que hacer una macro nueva.

Dime con cuál opción te ayudo, o bien, hacemos la primera opción, capturas en el userform el código, la revisas y si no te gusta la hacemos directamente en la hoja.

Envíame tu archivo,

Mi correo [email protected]

En el asunto del correo escribe tu nombre de usuario “Marcos Diaz” y el título de esta pregunta.

Este sería el código para los eventos de tu hoja

Private Sub Worksheet_Change(ByVal Target As Range)
'Por.Dante Amor
    If Target.Row < 7 Then Exit Sub
    If Not Intersect(Target, Columns("C")) Is Nothing Then
        'Valida la izquierda y la derecha
        If Left(Target, 4) = "0100" And Right(Target, 10) = Range("D3") Then
            Application.ScreenUpdating = False
            Application.EnableEvents = False
            Cells(Target.Row, "D") = "PASA"
            Cells(Target.Row + 1, "B") = Cells(Target.Row, "B") + 1
            Range("B7:G7").Copy: Cells(Target.Row + 1, "B").PasteSpecial xlFormats
            Application.CutCopyMode = False
            Application.EnableEvents = True
            Cells(Target.Row + 1, "C").Select
        Else
            Cells(Target.Row, "D") = "NO PASA"
            MsgBox "Codigo Incorrecto", vbCritical
        End If
    End If
    '
    If Not Intersect(Target, Columns("F")) Is Nothing Then
        'Valida la izquierda y la derecha
        If Left(Target, 4) = "0110" And Right(Target, 10) = Range("D3") Then
            Cells(Target.Row, "G") = "PASA"
            Cells(Target.Row + 1, "C").Select
        Else
            Cells(Target.Row, "G") = "NO PASA"
            MsgBox "Codigo Incorrecto", vbCritical
        End If
    End If
End Sub
'
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Por.Dante Amor
    n = 0
    For i = 7 To Range("C" & Rows.Count).End(xlUp).Row + 1
        If Cells(i, "D") = "NO PASA" Or Cells(i, "C") = "" Then
            u = i: col = "C"
            Exit For
        End If
        n = n + 1
        If n = Range("E5") Then
            If Cells(i, "F") = "" Then
                u = i: col = "F"
                Exit For
            Else
                If Cells(i, "G") = "NO PASA" Then
                    u = i: col = "F"
                    Exit For
                End If
                n = 0
            End If
        End If
    Next
    Application.EnableEvents = False
    Cells(u, col).Select
    Application.EnableEvents = True
End Sub

'S aludos. Dante Amor. Recuerda valorar la respuesta. G racias

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas