Como añadir las iniciales del nombre y apellidos en uno de los campos de una tabla

Tengo una tabla con un campo llamado [Alumno/a] que cotiene los apellidos y el nombre de alumnos separados por una coma. Esta tabla tiene más campos, pero el que me interesa ahora es uno que se llama [Iniciales] y que está en blanco. Mi pregunta es la siguiente: "¿Cómo hago para que en ese campo se vayan agregando las iniciales de cada alumno?

Mi problema no es el código para crear las iniciales. Ya lo tengo hecho y es el siguiente:

Sub iniciales()
    Dim letras1 As String
    Dim letras2 As String
    Dim n As Long
    Dim A As Long
        'Analizamos las iniciales del nombre
            letras1 = Mid(txt_nombre.Value, 1, 1)
            For n = 1 To Len(txt_nombre.Value) 'Bucle desde calculando la longitud total del nombre
            If Mid(txt_nombre.Value, n, 1) = " " And Mid(txt_nombre.Value, n + 1, 1) <> "d" And Mid(txt_nombre.Value, n + 1, 1) <> "l" Then
                letras1 = letras1 & Mid(txt_nombre.Value, n + 1, 1)
            End If
            Next
        'Analizamos las iniciales del apellido
            letras2 = Mid(txt_apellidos.Value, 1, 1)
            For A = 1 To Len(txt_apellidos.Value)  'Bucle desde calculando la longitud total del apellido
            If Mid(txt_apellidos.Value, A, 1) = " " And Mid(txt_apellidos.Value, A + 1, 1) <> "d" And Mid(txt_apellidos.Value, A + 1, 1) <> "l" Then
                letras2 = letras2 & Mid(txt_apellidos.Value, A + 1, 1)
            End If
            Next
        txt_iniciales = letras1 & letras2 'Asignamos las iniciales al campo inicales
End Sub

En donde estoy perdido es en cómo ir cargando las iniciales de cada alumno (el valor de txt_iniciales) en cada uno de los registros.

Respuesta
1

dim rs as dao.recordset

Rs. Openrecordset (SELECT * FROM NOMBRETABLA)

rs.movefirst

while not rs.eof

rs(0)=txt_iniciales

rs.movenext

loop

Pruebalo, ya que lo escribí de memoria.

¿Es posible que la segunda línea se así?

    rs.OpenRecordset "SELECT * from Config_alumnado"

Por otro lado, cómo le digo que las iniciales se carguen en el campo [iniciales]. 

En vez de rs(0) identifiquelo así: rs("Iniciales")

1 respuesta más de otro experto

Respuesta
2

Supongamos que tengo una tabla(no sé como la tienes tú)

Si no quieres hacerlo en código, te lo pongo en una consulta de actualización, donde, debajo de Iniciales, en la casilla Actualizar a le pongo lo que ves en la ventana Zoom

Al ejecutarla

Si lo que tienes es un formulario, en el evento Después de actualizar del cuadro de texto Nombre puedes poner

Iniciales = Left([Nombre], 1) & "" & Mid([Nombre], InStr([Nombre], ",") + 2, 1)

Así, en el momento que escribas un nombre y pulses Enter, en Iniciales te pondrá las que correspondan.

Ese código no me funcionaría. Por ejemplo, en el caso de un nombre como "Muñoz de la Cruz Gutiérrez, Alfonso", las iniciales tendrían que ser AMCG (no se tiene en cuenta la "de", ni la "la").

Si hubiese alguna forma de hacer eso en una sola linea dentro de una consulta de actualización estaría muy bien porque desconocía su uso hasta que me hablastes de ellas y me parece un objeto muy útil.

Si un alumno se llama como lo has puesto, se merece que lo echen del colegio por cursi. Mira, supongamos que tengo una tabla

Como puedes ver, excepto María los demás son de la aristocracia( y ya se sabe que pasó con ellos en la Revolución Francesa). Le he puesto un campo Aux(que no sería necesario), para que se vea lo que queda después de reemplazar.

En un formulario( que podría perfectamente ser continuo para "colocar" todas las iniciales de todos los alumnos), pero que lo pongo como único para que se vea el proceso

Cuando pulso el botón

Me voy al siguiente

Cuando pulso el botón

En el siguiente

Al pulsar el botón

Y por fin llegamos a María, la burguesa

Al pulsar

El código del botón es

Private Sub Comando15_Click()
Aux = Replace([Nombre], " de la ", "/")
Aux = Replace([Aux], " y ", "/")
Aux = Replace([Aux], " de los ", "/")
Aux = Replace([Aux], " ", "/")
Aux = Replace([Aux], ",", "")
Dim a As Byte, primero, segundo, tercero, cuarto
a = Len([Aux]) - Len(Replace([Aux], "/", ""))
Select Case a
Case Is = 3
primero = Left([Aux], InStr([Aux], "/") - 1)
Dim resto
resto = Mid([Aux], InStr([Aux], "/") + 1)
segundo = Left("" & resto & "", InStr("" & resto & "", "/") - 1)
Dim otro
otro = Mid("" & resto & "", InStr("" & resto & "", "/") + 1)
tercero = Left("" & otro & "", InStr("" & otro & "", "/") - 1)
cuarto = Mid("" & otro & "", InStr("" & otro & "", "/") + 1)
Iniciales = Left([cuarto], 1) & "" & Left([primero], 1) & "" & Left([segundo], 1) & "" & Left([tercero], 1)
Case Is = 2
primero = Left([Aux], InStr([Aux], "/") - 1)
Dim quedan
quedan = Mid([Aux], InStr([Aux], "/") + 1)
segundo = Left("" & quedan & "", InStr("" & quedan & "", "/") - 1)
cuarto = Mid("" & quedan & "", InStrRev("" & quedan & "", "/") + 1)
Iniciales = Left([cuarto], 1) & "" & Left([primero], 1) & "" & Left([segundo], 1)
End Select
End Sub

En esencia, que vaya reemplazando las posibles cadenas, de, y, de los, espacio, coma, etc por / hasta dejarlo como queda en Aux. Luego que cuente cuantas barras hay(para saber el número de nombres y apellidos) y en función de eso que coja la primera letra de cada subcadena y la ponga en iniciales.

Lógicamente habría que poner que fuera desde el primer registro hasta el último haciendo esos cálculos.

Antes de nada, Icue, muchas gracias por el tiempo que te has tomado para responderme a mi problema. Es de agradecer, y mucho.

Sobre el nombre ese tan largo me lo inventé (no quiero poner nombres reales), pero es verdad que hay alumnos, pocos que tienen nombres compuestos (algunos incluco con un guión). Para solucionar ese problema creé el código que puse en la pregunta que me funcionaperfectamente. El problema es que tengo en la tabla más de 2000 alumnos y necesito que, de alguna forma, el proceso de creación de las iniciales en el campo [Iniciales] se haga de forma automática y no uno por uno. Ahí es donde precisamente me pierdo. No soy capaz de hacer lo que dices en el último párrafo de tu respuesta.

La solución me la diste en la otra pregunta que te hice sobre como reemplazar con código parte de una cadena. Ahí me decías cómo entrar en cada campo y ejecutar un código para reemplazar. El problema es que al ejecutar el código en el evento al "salir" del subformulario me salía un error como si no encontrase el campo donde tenía que hacer los cambios. Si ese problema se solucionase me darías respuestas al problema que tengo ahora.

Gracias de nuevo por tu tiempo.

Te decía que habría que ponerle la instrucción para que cambiara registro a registro. Podrías usar Do while pero prefiero que uses un formulario continuo con un botón para que veas el proceso.

En el evento Al hacer clic del botón pon

Docmd. Gotorecord,, acfirst

dim i as integer

for i=1 to me.recordset.recordcount

Aquí iría toda tu instrucción

Docmd. Gotorecord,, acnext

next

Docmd. Gotorecord,, acfirst

Es decir

Vete al primer registro. Y declara la variable i como integer.

Para i=1 hasta el último registro(por eso cuenta los registros que hay en el formulario, me.recordset.recordcount) vete "recorriéndolos" uno a uno y haciendo el cambio, y cuando llegues al último y hayas hecho el cambio te vuelves al principio.

Nada Icue. Sigo teniendo problemas con el código. Voy a intentar explicar todo con imágenes y lo que sea necesario para ver qué está pasando.

Lo primero, lo del botón no me funciona. Por otro lado, me parece más útil la idea que me diste hace un par de días: ejecutar el código poniéndolo en el evento "Al salir" del subformulario.

Parto del siguiente diseño (los nombres no son reales):

El diseño consiste en un formulario principal con un control de pestañas. En una de las pestañas está el desplegable con el nombre de un colegio (CEIP Juan Sebastián Elcano) y debajo el subformulario.

El valor de ese campo está vinculado con el campo [Centro] de la tabla que está en el subformulario de abajo llamado "Subformulario_Config_alumnado". Este subformulario lo tengo, como bien sabes, en vista hoja de datos.

He intentado usar código, como me dijiste en otro momento, en vez de vincular campos principales y secundarios pero no lo he conseguido. Me sale un error.

Volviendo a lo que nos ocupa, por simplificar, lo que he intentado hacer es simplemente que el campo [iniciales] de todos los registros se rellene con "INI". Es simplemente por probar que consigo escribir todos los registros de este campo. Una vez lo consiguiese, pasaría a meter todo el código que calcula las iniciales...

Pues bien, cuando salgo del subformulario, el campo [Iniciales], al que he puesto en la pestaña "Otras", como nombre, "txt_iniciales", sigue vacío.

El código es el siguiente:

DoCmd.GoToRecord , , acFirst
Dim i As Integer
For i = 1 To Me.Recordset.RecordCount
txt_iniciales = "INI"
DoCmd.GoToRecord , , acNext
Next
DoCmd.GoToRecord , , acFirst

¿Qué está mal en este código para que "Al salir" del subformulario, el campo [Iniciales] o txt_iniciales, siga en blanco? Si este problema se solucionase creo que sabría hacer lo de poner las iniciales de cada alumno y alumna en cada registro.

Ya lo he solucionado con este código:

    Set rst = CurrentDb.OpenRecordset("Config_alumnado")
        rst.MoveFirst
        Do Until rst.EOF
            rst.Edit
            rst("iniciales") = "INI"
            rst.Update
            rst.MoveNext
        Loop
     rst.Close
     Set rst = Nothing

Me rellena el campo [Iniciales] de todos los registros. Pero me encuentro con el problema que tenía cuando me hablaste de las consultas de actualización... Por simplificar, añadí en el código un msgbox para que me devolviese el contenido del campo [Nombre], al que he llamado txt_nom. El código es el siguiente:

    Set rst = CurrentDb.OpenRecordset("Config_alumnado")
        rst.MoveFirst
        MsgBox txt_nom
        Do Until rst.EOF
            rst.Edit
            rst("iniciales") = "INI"
            rst.Update
            rst.MoveNext
        Loop
     rst.Close
     Set rst = Nothing

Mi sorpresa es que me devuelve el contenido vacío. Y si le pongo msgbox [Nombre] me da el error 2465. En definitiva, no consigo acceder al contenido de los campos del subformulario (ni a este campo, ni a ningún otro).

Solucionado ya el primer problema, me encuentro con este nuevo problema que no sé solucionar.

Sigo sin entender el motivo de usar un formulario en vista hoja de datos, personalmente no les veo ninguna utilidad. Si tengo un formulario con un control de pestañas, donde en la pestaña Página2 tengo un combinado donde voy a elegir el país, y un subformulario, en un principio, con todos los alumnos.

Si elijo un país, en este caso España

Me deja el subformulario sólo con aquellos registros de la tabla Alumnos en que su país sea España.

Si ahora pulso el botón

El código del evento Después de actualizar del combinado es

Me.Alumnos.Form.RecordSource = "select * from alumnos where pais like '" & Me.ElegirPais & "'"

Y el código del evento Al hacer clic del subformulario

Private Sub Comando5_Click()
DoCmd.GoToRecord , , acFirst
Dim i As Integer
For i = 1 To Me.Recordset.RecordCount
Pais = Replace([Pais], "España", "Cartagena")
End Sub

Lo he puesto sencillo por aprovechar una tabla que tenía.

Mierda, he pulsado sin querer lo de Enviar. Donde yo pongo

Replace...

Tu tienes que poner tu instrucción

Gracias de nuevo. ¡Qué paciencia estás teniendo conmigo!

Hay dos cosas que no funcionan:

La primera: el código del desplegable.

Me.Config_alumnado.Form.RecordSource = "select * from Config_alumnado where centro like '" & Me.cmdcentro & "'"

Al seleccionar un valor diferente en el desplegable me sale un error en cmdcentro: "Error de compilación. No se encontró el método o el dato miembro". "cmdcentro" es el nombre del desplegable.

Lo segundo, tengo la vista hoja de datos porque los datos del alumnado me vienen en una hoja de cálculo de forma que, para mí, lo fácil es copiar y pegar en el subformulario. Ese es el motivo.

Sigo teniendo un problema que parece tonto pero que es la clave para solucionar todo: no consigo leer el contenido de ningún campo de la tabla del subformulario. Por ejemplo, si pongo el siguiente código en el evento "Después de insertar" (creo que esto haría las veces del botón una vez que pegue los registros):

msgbox txt_NIE (por ejemplo o con cualquier otro campo) me sale la ventana sin nada

msgbox [NIE] me da el siguiente error: "El miembro ya existe en un módulo de objeto del que proviene".

Por si es importante te comento que la tabla del formulario principal, en donde se encuentra el objeto desplegable, es diferente a la tabla del subformulario.

Por partes

1º ¿Cuántas columnas tiene el combinado? ¿Cuál es la columna dependiente?. Si lo de Centro es la segunda, el código debería ser

me.alumnos.form.recordsource="select * from alumnos where centro like '" & me.cmdcentro.column(1) & "'"

En Vb la primera columna es 0.

2º Si el "archivo" lo entregan en formato de Excel, se puede importar y con esa tabla hacer el formulario como se quiera. Pero si lo que haces, es pegarlo directamente en el formulario la instrucción Después de insertar no sirve. Y a partir de ahí no he he entendido nada y mucho menos lo de msg

Buenos días Icue. Voy a intentar ser lo más claro posible y, si te parece, vamos a resolver esto por partes. Lo primero es conseguir que el código del desplegable funcione ya que sigue sin funcionar.

He creado una base de datos sencilla para probar todos los códigos que me mandas. Te mando los pantallazos. Esto es lo que he hecho:

El formulario principal "Colegios" tiene como origen del registro la tabla "Colegios" con un solo campo [colegio]

El "Subformulario Alumnos" tiene como origen del registro la tabla "Alumnos" con cuatro campos: [Nombre], [Apellidos], [Iniciales] y [Colegio].

El desplegable tiene como columna dependiente la 1.

En el evento Después de actualizar del combinado he puesto este código y no funciona:

Me.alumnos.Form.RecordSource = "select * from alumnos where colegio like '" & Me.cmdcolegio.Column(1) & "'"

Una pregunta Icue, ¿sería posible enviarte la base de datos que he hecho para probar lo que me dices?

Creo que es lo mejor. Mi correo es [email protected]

Si la mandas, en el asunto del mensaje pon tu alias Pedro Muñoz, ya que si no sé quien me escribe ni los abro.

Muchas gracias por el arreglo. Siempre he hecho la vinculación, dentro de la pestaña Datos, entre el campo principal y el secundario pero no ponía código en el desplegable. A partir de ahora lo haré como me has puesto en la BBDD.

Ahora queda el segundo problema que lo tengo casi resuelto: cómo calcular las iniciales de cada registro y escribirlo en el campo correspondiente.

He puesto el código en el evento "Al salir" tal y como me dijiste. Pero tengo un problema: el código me calcula las iniciales del primer alumno, o bien las iniciales del alumno donde está posicionado el cursor. Y esas iniciales me las repite en todos los registros de la tabla del subformulario. 

Es decir, el cálculo de las iniciales se hace siempre sobre el mismo registro. Así es como queda:

El código que estoy utilizando es el siguiente:

Private Sub Subformulario_config_alumnado_Exit(Cancel As Integer)
Dim rst As dao.Recordset
Dim letras1 As String
Dim letras2 As String
Dim letras3 As String
Dim varnom As String
Dim varape1 As String
Dim varape2 As String
Dim n As Long
Dim A As Long
Set rst = CurrentDb.OpenRecordset("Config_alumnado")
rst.MoveFirst
Do Until rst.EOF
    rst.Edit
    varnom = Forms!Configurar![Subformulario_config_alumnado].Form![Nombre]
    varape1 = Forms!Configurar![Subformulario_config_alumnado].Form![Apellido_1]
    varape2 = Forms!Configurar![Subformulario_config_alumnado].Form![Apellido_2]
        'Analizamos las iniciales del nombre
            letras1 = Mid(varnom, 1, 1)
            For n = 1 To Len(varnom) 'Bucle desde calculando la longitud total del nombre
            If Mid(Nombre, n, 1) = " " And Mid(varnom, n + 1, 1) <> "d" And Mid(varnom, n + 1, 1) <> "l" Then
                letras1 = letras1 & Mid(varnom, n + 1, 1)
            End If
            Next
        'Analizamos las iniciales del apellido1
            letras2 = Mid(varape1, 1, 1)
            For A = 1 To Len(varape1)  'Bucle desde calculando la longitud total del apellido
            If Mid(varape1, A, 1) = " " And Mid(varape1, A + 1, 1) <> "d" And Mid(varape1, A + 1, 1) <> "l" Then
                letras2 = letras2 & Mid(varape1, A + 1, 1)
            End If
            Next
        'Analizamos las iniciales del apellido2
            letras3 = Mid(varape2, 1, 1)
            For A = 1 To Len(varape2)  'Bucle desde calculando la longitud total del apellido
            If Mid(varape2, A, 1) = " " And Mid(varape2, A + 1, 1) <> "d" And Mid(varape2, A + 1, 1) <> "l" Then
                letras3 = letras3 & Mid(varape2, A + 1, 1)
            End If
            Next
        campoini = letras1 & letras2 & letras3 'Asignamos las iniciales al campo inicales
    rst("iniciales") = campoini
    rst.Update
    rst.MoveNext
Loop
rst.Close
Set rst = Nothing
End Sub

En un formulario tipo continuo, sólo tiene existencia real el registro activo, el que está señalado por la punta de flecha. Lo demás son imágenes virtuales, que sólo tendrán existencia real cuando se conviertan en activos. Para eso existe el evento Al activar el registro.

Te decía que no le veía utilidad al subformulario en vista hoja de datos, ya que no te deja ponerle, por ejemplo, un botón, que cuando reciba el enfoque, por un lado convierta el subformulario en el objeto activo, y por otro ejecute la instrucción de buscar las iniciales.

Lo siento, pero tal como quieres hacerlo, no se me ocurre la solución.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas