Saludos de nuevos a todas y todos. Me dirijo de nuevo al foro porque me gustaría hacer una cosa y, aunque viendo macros tengo una ligera idea de lo que habría que hacer, no sé por dónde empezar, y además tengo experiencia en que cuando he preguntado algo, la solución que me han dado los foreros son mucho mejores que lo que se me ocurre. Bueno, ahí va:
Estoy preparando un sociograma para mi colegio, en el que los estudiantes escogen con quién quieren jugar, para concluir quiénes son los líderes. Lo he hecho con una madriz de doble entrada en la que marcamos quién ha votado a quien, hacemos un recuento, y los más votados son los líderes. Hasta aquí bien, sin macros.
Aquí viene mi duda: me gustaría tener una macro que leyera los datos de la matriz e identificara si un estudiante a votado a otro, y viceversa, para detectar las relaciones positivas bidireccionales (Juan vota a María, y María vota a Juan) para poder hacer grupos de trabajo adecuadamente.
He imaginado una macro que identifique las celdas marcada con diferentes de "" (poque solo se marcan con "X") que coincidan en la fila y columna de ambos estudiantes, y si es así, que se vaya a una columna y copie y peque el nombre de los estudiantes, y que empiece a leer la tabla de nuevo, y si encuentra otra relación bidireccional, se venga a la celda anterior (pero si ya ha escrito algún dato, pues que baje una fila y lo ponga ahí)... los que sabéis un poco os estaréis riendo de mi planteamiento jeje.
Bueno, subo el archivo y espero vuestra ayuda, como siempre. Gracias.
Adjunto | Tamaño |
---|---|
![]() | 41.95 KB |
Acabo de hacer este intento de código para que lea qué estudiantes han seleccionado al estudiante 1 (los estudiantes que emiten el voto son las filas, y los receptores son las columnas). Con esta macro identifico quién ha votado al estudiante 1 (aunque los va copiando y pegando dejando un espacio entre ellos y me gustaría que los fuera poniendo seguidos, pero algo es algo)
Sub comparar()
a = 1
For i = 2 To 20
'Contador = c
Cells(i, 2).Select
If ActiveCell = "X" Then
ActiveCell.Offset(0, -a).Select
ActiveCell.Copy
ActiveCell.Offset(35, 0).Select
If ActiveCell <> "" Then
ActiveCell.Offset(1, 0).Select
ActiveCell.PasteSpecial
ActiveCell.Offset(-35 + c - 1, 0).Select
ActiveCell.Offset(0, a).Select
End If
ActiveCell.PasteSpecial
ActiveCell.Offset(-35 + c, 0).Select
ActiveCell.Offset(0, a).Select
End If
ActiveCell.Offset(1, 0).Select
'a = a + 1
Next
End Sub
Cuando tienes en tus votos unos votos recíprocos, en tu matriz tendrás una simetría respecto de la diagonal
he coloreado unas parejas en tu ejemplo:
aquí por ejemplo E2 vota a E1 y E1 a E2
E3 y E1 es otra pareja, y E4 y E5 otra
puedes hacer un bucle que recorra las filas y dentro de este otro que recorra las columnas y comprobar si lo que tienes en fila-columna coincide con lo que tienes en columna-fila
algo así (bueno, veo que tienes X mayúsculas y minúsculas. a mí me gusta más poner un 1 que una x, pero bueno, eso es lo de menos)
Function parejas() As String
Dim fila, columna
Const celdaesquina = "A1"
parejas = ""
For fila = 1 To 20
For columna = fila + 1 To 20
If Not IsEmpty(Range(celdaesquina).Offset(fila, columna).Value) Then
If Range(celdaesquina).Offset(fila, columna).Value = Range(celdaesquina).Offset(columna, fila).Value Then
parejas = parejas & Range(celdaesquina).Offset(fila, 0).Value & Range(celdaesquina).Offset(0, columna).Value & "; "
End If
End If
Next
Next
End Function
------
Ya sé Excel, pero necesito más.
Muchas gracias. Es increíble como al final la variable "parejas" (es una variable ¿no?) tiene como valor los nombres de los estudiantes.
Entiendo que se va a ver los nombres de los estudiantes recíprocos junto, sin espacio, y un ; entre cada pareja. No es lo ideal porque no es estético al verse los nombres juntos, pero me parece increíble que haga lo que ya hace, de verdad).
Ya he conseguido poner los nombres separados (bastaba con poner & " y " entre los dos rangos y listo. Gracias. También le he dicho que la variable "parejas" vuelva a ser igual a "" tras cada ciclo en el for fila, y así cada vez que pegue el valor de "parejas" solo abarca el nombre de una pareja (la más reciente encontrada).
Ahora trato de investigar como hacer que pegue el valor de la variable "parejas" en una celda y que, cuando vuelva a encontrar otra relación recíproca, se vaya a la misma celda pero bajando una fila, para aglutinar todas las parejas en una columna pero cada pareja en una fila. A ver si lo consigo!
Perdón por escribir tantas veces, pero ya encontré la manera: con un acumulador = acumulador + 1 justo debajo de cada copiado de parejas, me identifica el número de parejas encontradas y baja una fila cada vez. Ya lo tengo. Muchas gracias por todo.
Buenas noches de nuevo. Ahora llevo bastante tiempo mirando y no encuentro la forma de ejectura la macro con un botón de acción. He intentado asociar directamente el botón a esta macro, pero nos sale en el listado de macros del libro; tampoco creando una macro que llame a esta macro que quiero ejecutar... necesito ayuda, please.
Pensaba que con una simple subrutina que llamase a la función se haría, pero veo que a priori no me sale, investigaré...
Lo que puse como ejemplo era una función
Como parece que quieres escribir en varias celdas el resultado, no deberías hacerlo como función, sino como un procedimiento SUB, que sí puedes asociar a un botón.
En teoría, si llamas a la función desde otro procedimiento sí debería funcionar. Dependerá de la hoja activa y del resto de cosas que estés suponiendo implícitamente en tu procedimiento.
Adjunta un ejemplo de lo que estás intentando hacer para poder hacer pruebas y averiguar por qué no funciona.
------
Ya sé Excel, pero necesito más.