Celda para un solo carácter con pase a siguiente sin esperas

Esgrimidor

New Member
Joined
Jun 25, 2009
Messages
34
Celda para un solo carácter con pase a siguiente sin esperas.

¿ Cómo se configura una celda excel para que sólo sea posible meter un carácter y que tras introducirlo salte el cursor a la celda siguiente inferior ?

Por ejemplo el dígito 1 hace que se escriba el uno y luego el cursor pase a la celda inferior. Y si le damos a enter que pase a la celda siguiente sin escribir nada en la celda actual.
 
No me funciona bien





el simbolo que me dibuja en la columna F es ü y tras darle a enter el cursor se va al comienzo de la siguiente fila o línea, no se mantiene en la columna F.

Qué estoy haciendo mal ?
 
Upvote 0

Excel Facts

Test for Multiple Conditions in IF?
Use AND(test, test, test, test) or OR(test, test, test, ...) as the logical_test argument of IF.
Con un par de cambiocitos funciona muy bien.

Code:
Option Explicit
Sub SetKeys()
    Application.OnKey "{Enter}", "RunIt"
    Application.OnKey "~", "RunIt"
End Sub
Sub UnsetKeys()
    Application.OnKey "{Enter}"
    Application.OnKey "~"
End Sub
Sub RunIt()
    Dim rng As Range
    
    Const CHECKMARK_COLUMN As Long = 4  'D:D
    Const CHECK_STRING As String = "ü"  'Windings font
    
    If TypeName(Selection) = "Range" Then
        Set rng = Selection
    Else
        Exit Sub
    End If
    
    If rng.Column = CHECKMARK_COLUMN Then
    
        If rng.Value = CHECK_STRING Then
            rng.Value = ""
        Else
            rng.Value = CHECK_STRING
            rng.Font.Name = "Wingdings"
        End If
    End If
    
    Select Case Application.MoveAfterReturnDirection
        Case XlDirection.xlDown
            rng.Offset(1).Select
        Case XlDirection.xlToRight
            rng.Offset(, 1).Select
        Case XlDirection.xlUp
            rng.Offset(-1).Select
        Case XlDirection.xlToLeft
            rng.Offset(, -1).Select
    End Select
    
End Sub
 
Upvote 0
Actualmente, si usted pone el siguiente en el módulo para la hoja creo que se puede desocupar un poco de tener que correr UNSETKEYS().
Code:
Option Explicit
Private Const mc_intCol As Integer = 4  ' only target column 4
Private Sub Worksheet_Activate()
    If ActiveCell.Column = mc_intCol Then
        SetKeys
    Else
        UnsetKeys
    End If
End Sub
Private Sub Worksheet_Deactivate()
    UnsetKeys
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Column = mc_intCol Then
        SetKeys
    Else
        UnsetKeys
    End If
End Sub
 
Upvote 0
Funciona estupendamente bien.

Me queda por probar lo de unsetkeys que no entiendo muy bien lo que quiere decir el módulo de la hoja.
No se si es con botón derecho sobre el tab de la hoja, pero es que me parece que tengo algo metido allí ya.
 
Upvote 0
Actualmente, si usted pone el siguiente en el módulo para la hoja creo que se puede desocupar un poco de tener que correr UNSETKEYS().
Code:
Option Explicit
Private Const mc_intCol As Integer = 4  ' only target column 4
Private Sub Worksheet_Activate()
    If ActiveCell.Column = mc_intCol Then
        SetKeys
    Else
        UnsetKeys
    End If
End Sub
Private Sub Worksheet_Deactivate()
    UnsetKeys
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Column = mc_intCol Then
        SetKeys
    Else
        UnsetKeys
    End If
End Sub


¿ Dónde pongo este código ?
¿ En el mismo sitio que puse el otro ?

Gracias
 
Upvote 0
¿ Dónde pongo este código ?
¿ En el mismo sitio que puse el otro ?

Gracias

De Excel mismo (no del editor de VB) haz un cliq-derecho sobre la etiqueta de la hoja. En el menú contextual usted verá una opción como "View Code". Si usted selecciona ella le lleva directamente al módulo que corresonde a tal hoja. [También, una ruta alternative es escoger el módulo en el editor si tiene la ventana Exploradora de Proyectos abierto con hacer cliq-doble sobre el nombre de la hoja.]
 
Upvote 0
Hola,

He aqui una adaptacion de un metodo que compuse ultimamente .

Copia el codigo siguiente en el modulo de la hoja (Worksheet module).Una vez copiado el codigo, cada vez que selecciones una celda en la columna F:F y le des a cualquier tecla (excepto aquellas para navigar la hoja) el simbolo ües automaticamente insertado en la celda activa y la selection pasa directamente a la celda siguiente.
Sin embargo, si la tecla "Enter" es golpeada la celda siguiente es activada sin insertar el simbolo.

Codigo : (Worksheet module)

Code:
Option Explicit
 
Private Type POINTAPI
    x As Long
    y As Long
End Type
 
Private Type MSG
    hwnd As Long
    Message As Long
    wParam As Long
    lParam As Long
    time As Long
    pt As POINTAPI
End Type
 
Private Declare Function WaitMessage Lib "user32" () As Long
 
Private Declare Function PeekMessage Lib "user32" _
Alias "PeekMessageA" _
(ByRef lpMsg As MSG, ByVal hwnd As Long, _
ByVal wMsgFilterMin As Long, _
ByVal wMsgFilterMax As Long, _
ByVal wRemoveMsg As Long) As Long
 
Private Declare Function TranslateMessage Lib "user32" _
(ByRef lpMsg As MSG) As Long
 
Private Declare Function PostMessage Lib "user32" _
Alias "PostMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
 
Private Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
 
Private Const WM_KEYDOWN As Long = &H100
Private Const PM_REMOVE  As Long = &H1
Private Const PM_NOREMOVE As Long = &H0
Private Const WM_CHAR    As Long = &H102
Private bExitLoop As Boolean
 
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
 
    [COLOR=seagreen]'intercept user keystrokes within column F:F[/COLOR]
    If Union(Target, Columns("F:F")).Address = _
    Columns("F:F").Address Then
        StartKeyWatch
    Else
        StopKeyWatch
    End If
 
End Sub
 
Private Sub StartKeyWatch()
 
    Dim msgMessage As MSG
    Dim bCancel As Boolean
    Dim iKeyCode As Integer
    Dim lXLhwnd As Long
 
    [COLOR=seagreen]'handle the ESC key.[/COLOR]
    On Error GoTo errHandler:
    Application.EnableCancelKey = xlErrorHandler
  [COLOR=seagreen] 'initialize this boolean flag.[/COLOR]
    bExitLoop = False
    [COLOR=seagreen]'get the app hwnd.[/COLOR]
    lXLhwnd = FindWindow("XLMAIN", Application.Caption)
    Do
        WaitMessage
      [COLOR=seagreen]  'check for a key press and remove it from the msg queue.[/COLOR]
        If PeekMessage _
            (msgMessage, lXLhwnd, WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE) Then
         [COLOR=seagreen]  'strore the virtual key code for later use.[/COLOR]
[COLOR=seagreen]          [COLOR=black]iKeyCode = msgMessage.wParam[/COLOR]
           'translate the virtual key code into a char msg.
[/COLOR]           TranslateMessage msgMessage
            PeekMessage msgMessage, lXLhwnd, WM_CHAR, _
            WM_CHAR, PM_REMOVE
          [COLOR=seagreen] 'for some obscure reason, the following[/COLOR]
[COLOR=seagreen]         'keys are not trapped inside the event handler[/COLOR]
            [COLOR=seagreen]'so we handle them here.[/COLOR]
            If iKeyCode = vbKeyBack Then SendKeys "{BS}"
            If iKeyCode = vbKeyReturn Then SendKeys "{ENTER}"
           [COLOR=seagreen]'assume the cancel argument is False.[/COLOR]
            bCancel = False
            [COLOR=seagreen]'the VBA RaiseEvent statement does not seem to return ByRef arguments[/COLOR]
            [COLOR=seagreen]'so we call a KeyPress routine rather than a propper event handler.[/COLOR]
            Sheet_KeyPress _
            ByVal msgMessage.wParam, ByVal iKeyCode, ByVal ActiveCell, bCancel
           [COLOR=seagreen]'if the key pressed is allowed post it to the application.[/COLOR]
            If bCancel = False Then
                PostMessage _
                lXLhwnd, msgMessage.Message, msgMessage.wParam, 0
            End If
        End If
errHandler:
     [COLOR=seagreen]  'allow the processing of other msgs.[/COLOR]
        DoEvents
    Loop Until bExitLoop
 
End Sub
 
Private Sub StopKeyWatch()
 
   [COLOR=seagreen]'set this boolean flag to exit the above loop.[/COLOR]
    bExitLoop = True
 
End Sub
 
Private Sub Sheet_KeyPress _
(ByVal KeyAscii As Integer, ByVal KeyCode As Integer, _
ByVal Target As Range, Cancel As Boolean)
 
   [COLOR=seagreen]'which key has been pressed ?[/COLOR]
    Select Case KeyCode
 
        Case vbKeyTab, _
             vbKeyReturn, _
             vbKeyLeft, _
             vbKeyUp, _
             vbKeyRight, _
             vbKeyDown, _
             vbKeyDelete[COLOR=seagreen] 'if it is a navigation key do nothing.[/COLOR]
        
 
        Case Else [COLOR=seagreen]'else,cancel the key stoke and _[/COLOR]
[COLOR=seagreen]                 'run these lines instead.[/COLOR]
            Cancel = True
            With Target
                .Value = "ü"
                .HorizontalAlignment = xlCenter
                .Font.Name = "Wingdings"
            End With
            SendKeys "{ENTER}"
 
    End Select
 
End Sub

Saludos cordiales.
 
Upvote 0
De Excel mismo (no del editor de VB) haz un cliq-derecho sobre la etiqueta de la hoja. En el menú contextual usted verá una opción como "View Code". Si usted selecciona ella le lleva directamente al módulo que corresonde a tal hoja. [También, una ruta alternative es escoger el módulo en el editor si tiene la ventana Exploradora de Proyectos abierto con hacer cliq-doble sobre el nombre de la hoja.]

Muchas gracias Greg. Al principio parece que me fallaba al introducir el código :

Option Explicit
Private Const mc_intCol As Integer = 7 ' only target column 7
Private Sub Worksheet_Activate()
If ActiveCell.Column = mc_intCol Then
SetKeys
Else
UnsetKeys
End If
End Sub
Private Sub Worksheet_Deactivate()
UnsetKeys
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = mc_intCol Then
SetKeys
Else
UnsetKeys
End If
End Sub

Pero insistiendo e introduciendo este código de hoja al principio de la ventana Ver Código que aparece con click derecho sobre la hoja afecta parece ir bien. En cambio si lo colocaba al final parece que no.
Es que tengo también ya metido algún otro código anterior de hoja.....

He salido de la hoja y vuelto a entrar y me sigue funcionando bien la macro.

Muchas gracias.

Seguiré con las pruebas y si hay alguna variación te lo cuento.

besotene2.gif
 
Upvote 0
Hola,

He aqui una adaptacion de un metodo que compuse ultimamente .

Copia el codigo siguiente en el modulo de la hoja (Worksheet module).Una vez copiado el codigo, cada vez que selecciones una celda en la columna F:F y le des a cualquier tecla (excepto aquellas para navigar la hoja) el simbolo ües automaticamente insertado en la celda activa y la selection pasa directamente a la celda siguiente.
Sin embargo, si la tecla "Enter" es golpeada la celda siguiente es activada sin insertar el simbolo.

Codigo : (Worksheet module)

Code:
Option Explicit
 
Private Type POINTAPI
    x As Long
    y As Long
End Type
 
Private Type MSG
    hwnd As Long
    Message As Long
    wParam As Long
    lParam As Long
    time As Long
    pt As POINTAPI
End Type
 
Private Declare Function WaitMessage Lib "user32" () As Long
 
Private Declare Function PeekMessage Lib "user32" _
Alias "PeekMessageA" _
(ByRef lpMsg As MSG, ByVal hwnd As Long, _
ByVal wMsgFilterMin As Long, _
ByVal wMsgFilterMax As Long, _
ByVal wRemoveMsg As Long) As Long
 
Private Declare Function TranslateMessage Lib "user32" _
(ByRef lpMsg As MSG) As Long
 
Private Declare Function PostMessage Lib "user32" _
Alias "PostMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
 
Private Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
 
Private Const WM_KEYDOWN As Long = &H100
Private Const PM_REMOVE  As Long = &H1
Private Const PM_NOREMOVE As Long = &H0
Private Const WM_CHAR    As Long = &H102
Private bExitLoop As Boolean
 
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
 
    [COLOR=seagreen]'intercept user keystrokes within column F:F[/COLOR]
    If Union(Target, Columns("F:F")).Address = _
    Columns("F:F").Address Then
        StartKeyWatch
    Else
        StopKeyWatch
    End If
 
End Sub
 
Private Sub StartKeyWatch()
 
    Dim msgMessage As MSG
    Dim bCancel As Boolean
    Dim iKeyCode As Integer
    Dim lXLhwnd As Long
 
    [COLOR=seagreen]'handle the ESC key.[/COLOR]
    On Error GoTo errHandler:
    Application.EnableCancelKey = xlErrorHandler
  [COLOR=seagreen] 'initialize this boolean flag.[/COLOR]
    bExitLoop = False
    [COLOR=seagreen]'get the app hwnd.[/COLOR]
    lXLhwnd = FindWindow("XLMAIN", Application.Caption)
    Do
        WaitMessage
      [COLOR=seagreen]  'check for a key press and remove it from the msg queue.[/COLOR]
        If PeekMessage _
            (msgMessage, lXLhwnd, WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE) Then
         [COLOR=seagreen]  'strore the virtual key code for later use.[/COLOR]
[COLOR=seagreen]          [COLOR=black]iKeyCode = msgMessage.wParam[/COLOR]
           'translate the virtual key code into a char msg.
[/COLOR]           TranslateMessage msgMessage
            PeekMessage msgMessage, lXLhwnd, WM_CHAR, _
            WM_CHAR, PM_REMOVE
          [COLOR=seagreen] 'for some obscure reason, the following[/COLOR]
[COLOR=seagreen]         'keys are not trapped inside the event handler[/COLOR]
            [COLOR=seagreen]'so we handle them here.[/COLOR]
            If iKeyCode = vbKeyBack Then SendKeys "{BS}"
            If iKeyCode = vbKeyReturn Then SendKeys "{ENTER}"
           [COLOR=seagreen]'assume the cancel argument is False.[/COLOR]
            bCancel = False
            [COLOR=seagreen]'the VBA RaiseEvent statement does not seem to return ByRef arguments[/COLOR]
            [COLOR=seagreen]'so we call a KeyPress routine rather than a propper event handler.[/COLOR]
            Sheet_KeyPress _
            ByVal msgMessage.wParam, ByVal iKeyCode, ByVal ActiveCell, bCancel
           [COLOR=seagreen]'if the key pressed is allowed post it to the application.[/COLOR]
            If bCancel = False Then
                PostMessage _
                lXLhwnd, msgMessage.Message, msgMessage.wParam, 0
            End If
        End If
errHandler:
     [COLOR=seagreen]  'allow the processing of other msgs.[/COLOR]
        DoEvents
    Loop Until bExitLoop
 
End Sub
 
Private Sub StopKeyWatch()
 
   [COLOR=seagreen]'set this boolean flag to exit the above loop.[/COLOR]
    bExitLoop = True
 
End Sub
 
Private Sub Sheet_KeyPress _
(ByVal KeyAscii As Integer, ByVal KeyCode As Integer, _
ByVal Target As Range, Cancel As Boolean)
 
   [COLOR=seagreen]'which key has been pressed ?[/COLOR]
    Select Case KeyCode
 
        Case vbKeyTab, _
             vbKeyReturn, _
             vbKeyLeft, _
             vbKeyUp, _
             vbKeyRight, _
             vbKeyDown, _
             vbKeyDelete[COLOR=seagreen] 'if it is a navigation key do nothing.[/COLOR]
        
 
        Case Else [COLOR=seagreen]'else,cancel the key stoke and _[/COLOR]
[COLOR=seagreen]                 'run these lines instead.[/COLOR]
            Cancel = True
            With Target
                .Value = "ü"
                .HorizontalAlignment = xlCenter
                .Font.Name = "Wingdings"
            End With
            SendKeys "{ENTER}"
 
    End Select
 
End Sub
Saludos cordiales.

Muchas gracias Jaafar por tu aporte.
 
Upvote 0

Forum statistics

Threads
1,215,097
Messages
6,123,077
Members
449,094
Latest member
mystic19

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top