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.
2 Respuestas
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.
- Compartir respuesta
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.
- Compartir respuesta