elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


Tema destacado: Trabajando con las ramas de git (tercera parte)


  Mostrar Mensajes
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... 237
1  Foros Generales / Noticias / Re: Cuidado al guardar en Word: tus archivos ahora van a un lugar que no esperas en: 14 Octubre 2025, 19:22 pm
Citar
Al poner guardar cómo, en vez de mandarme a la carpeta donde ya está el archivo (quiero guardar otra versión), me pone una lista de carpetas y no sé qué más

Puedes ir directamente al viejo Guardar como, presionando la tecla F12

El nuevo Guardar como es más cómodo si trabajas con varias carpetas organizadas que va recordando Word, por ejemplo te mostrará las carpetas que usaste anteriormente, útil solo en esos casos, porque puedes elegir cualquiera de esas carpetas en lugar de buscarlas manualmente
2  Media / Diseño Gráfico / Re: ¿Cuales son los chat bots dibujantes suficientemente gratis? en: 14 Octubre 2025, 13:53 pm
Todo lo que es IA es muy costoso para la PC, requieres de un muy buen PC para trabajarlo razonablemente, por eso todo lo que es IA suele ser OnLine y con créditos. Hay programas que tratan de usar IA en local pero obviamente te van a pedir requerimientos abusivos, y si no requieren mucho es porque no son tan buenos XD
3  Programación / Programación General / Re: ¿Cuando se eliminan las variables iniciadas con var en AS de Macromedia Flash 5? en: 4 Octubre 2025, 01:14 am
En Flash5 (ActionScript 1.0) las variables declaradas (var) son locales, lo que implica que solo son accesibles en el bloque donde fueron declarados y se destruyen al finalizar dicho bloque, llámese bloque a lo que está entre las llaves, por ejemplo una FUNCTION, un IF, FOR, etc y por supuesto a las variables que son parte de la definición de esos bloques como los parámetros por valor y el famoso var i = 0 del FOR, lo mismo si declaras variables fuera de los bloques.

Las variables sin declarar (sin var) son globales, por lo que son accesibles desde cualquier parte, y se destruyen al finalizar la película.

Código
  1. function GenerarTipo1ySumar () {
  2.   var a = random(10);
  3.   var b = random(10);
  4.   Sumar();
  5.   trace("Generados: "+a+", "+b);
  6. }
  7. // Supongamos que tengo generar tipo 2, 3, etc, distintas fomas de generar.
  8. function Sumar () {
  9.   Resultado = a+b;
  10.   trace("Suma: "+Resultado);
  11. }

Estás declarando las variables locales a y b, así que solo son accesibles en ese bloque, cuando llamas a Sumar() es otro bloque y no sabe de la existencia de a y b. En Sumar() has asignado a una variable sin declarar: Resultado, está será global y accesible desde cualquier otra parte

Citar
No le veo sentido a pasar parámetros que voy a borrar, prefiero que las variables estén en el lv0 y las borro, así no tengo que andar pasando cosas, que supongo es un gasto extra.

Borrarlas? no puedes borrarlas, las variables globales solo se destruyen cuando la película finalice, es buena práctica usar parámetros y variables locales para que no te llenes de variables globales acumulando memoria, las variables globales deberían ser contaditas con los dedos para que no entren en conflicto con las variables locales, más cuando usas nombres muy genéricos como a, b, i, etc

Lo bueno de las versiones viejas de javascript es que puedes usar var para redeclarar variables o no simplemente no usarlas, no te dará problemas, es muy permisivo el lenguaje, pero en las versiones modernas ya se tiene la opción de forzar la declaración de variables y evitar la redeclaración de estas para parecerse, más a los leguajes de programación más estrictos
4  Programación / Ingeniería Inversa / Re: Ayuda Con El Crackme_8_by_ShoulcK en: 3 Octubre 2025, 03:54 am
Le eché un par de ojos y es un crackme bien enredado, seguramente por estar el delphi, con DeDe se tiene muuuucho más claro, pero x64dbg te pierdes, con OllyDBG puedes buscar los nombres de los eventos y se ven algo más claros, con IDA también se ven algo más claros.

Tan solo aclarar el uso de sbb, en el libro de Caos Reptante se describe brevemente, lo normal es verlo acompañado de un sub, eax, y edx, todo esto se utiliza para restar números mayores a 32bits (4Bytes), si uno conoce las instrucciones mul y div lo entiende un poco mejor porque esas instrucciones usan a edx y eax a la vez.

Al final se llega a la conclusión de:

Siendo una posible contraseña:

123456789123456789
01B69B4B ACD05F15
      x              y

Se tiene que obtener que:

x - 028E18DE = x xor 0796E723
y - B882ECC7 = y xor C88FFFC7

En caso del "Binary Paste" para aplicar la Fuerza Bruta en x64dbg sería así:



Hay que restarle 1 a ese ECX resultante porque se le aumenta +1 en el código independientemente de la comparación correcta

Y pensando en QWORDS que es como es en realidad sería:

Contraseña:
365495262636504647
5128001 40897647
            x

Se tiene que obtener que:

                x xor 0796E723 C88FFFC7 = x - 028E18DE B882ECC7
05128001 40897647 xor 0796E723 C88FFFC7 = 05128001 40897647 - 028E18DE B882ECC7
                      02846722 88068980 = 02846722 88068980


Si, porque la combinación de sub y sbb sirven para restar números mayores a 32bit, como 05128001 40897647 - 028E18DE B882ECC7 no se puede con los registros de 32bit se separa la parte alta en EDX y la parte baja en EAX y se opera:

Código
  1. mov edx, 05128001
  2. mov eax, 40897647
  3.  
  4. sub eax, B882ECC7 ; eax = 88068980 ; Carry Flag = 1
  5. sbb edx, 028E18DE ; edx = 02846723 - Carry Flag = 02846722

Resultado: 02846722 88068980



140897647-
 B882ECC7
 --------
 88068980


Ese 1 lo puse en rojo porque me lo presté para completar la resta, eso activa al Carry Flag para restárselo al siguiente resultado y dar el resultado correcto.
5  Informática / Software / Re: ADOBE ACROBAT PRO 64 bits en: 24 Septiembre 2025, 00:32 am
Hay que ver que herramientas de Acrobat utilizan, yo por ejemplo si requiero el Acrobat Pro porque utilizo herramientas avanzadas para la creación y validación de formularios masivos con javascript, también utilizo bastante la herramientas de Comprobaciones (preflight) para quitar/aislar elementos o marcas de agua, no he visto otro programa que lo haga. Aunque normalmente utilizo el Acrobat XI que es viejito pero tiene todas las opciones de la última versión y es increíblemente rápido, también está el Acrobat 2017 que es un excelente programa que siempre utilizaba y muy posiblemente me quede con él en lugar del XI. Las nuevas versiones son solo apariencia.

Una opción gratuita es PDF Gear, me parece que fue el primero en ofrecer herramientas de edición de texto e imágenes, y conversión de archivos de forma gratuita: https://www.pdfgear.com/es/download/

Ventajas:

- Peso del instalador: 130 MB
- Páginas: Permite eliminar, insertar, extraer, ordenar, rotar y recortar páginas
- Editar, puede editar texto del PDF, puede guardar, rotar, hacer OCR muy básico, reemplazar o eliminar imágenes del PDF
- Puede dividir y unir archivos  PDF
- Convertir: De PDF a Word, Excel, PowerPoint, PNG, JPG, TXT, HTML y viceversa de forma muy básica.
- Puede agregar, modificar y quitar hipervínculos
- Puede agregar una marca de agua de texto, números de página, encabezado y pie de página
- Permite poner y quitar contraseña de apertura (para quitar obviamente hay que tener la contraseña)
- Comentarios: Permite agregar Firma (no electrónica), texto, imagen, rellenar formularios, insertar formas básicas, mano alzada, líneas, cuadros, óvalos, notas, sellos, administrar comentarios, resaltar, subrayar, tachar
- OCR puntual básico (seleccionar área en página), OCR general al convertir a otro formato como Word pero de mala calidad
- Integra IA básica, requiere internet

Desventajas:

- Demora bastante iniciar el programa
- El OCR es malo, el OCR puntual trabaja regular
- La conversión de documentos es regular a mala
- Es algo lento
- No hay opciones de configuración
- Al iniciar el programa fuerza a que todos los archivos PDF se abran con PDF Gear por defecto

Pienso que para usuarios normales o de edición básica está bien
6  Programación / Ingeniería Inversa / Re: Solucion al Crackme 2 de alfa por Flamer en: 20 Septiembre 2025, 04:01 am
Bueno, yo también me voy a animar a explicarlo de forma detallada para refrescar la parte de representaciones de números negativos, que supongo yo es el objetivo del crackme

0. El crackme es: https://ns2.elhacker.net/crackmes/Crackme2alfa.zip

Código
  1. 00401372 | 8D45 AC                  | lea eax,dword ptr ss:[ebp-54]           |
  2. 00401375 | 50                       | push eax                                |
  3. 00401376 | 68 62124000              | push crackme.401262                     | 401262:"%i"
  4. 0040137B | E8 88010000              | call <JMP.&scanf>                       |
  5. 00401380 | 83C4 10                  | add esp,10                              |
  6. 00401383 | 8145 AC 0CFEFFFF         | add dword ptr ss:[ebp-54],FFFFFE0C      |
  7. 0040138A | 8B45 AC                  | mov eax,dword ptr ss:[ebp-54]           |
  8. 0040138D | 89C2                     | mov edx,eax                             | edx:EntryPoint
  9. 0040138F | 01D2                     | add edx,edx                             | edx:EntryPoint
  10. 00401391 | 8D0C10                   | lea ecx,dword ptr ds:[eax+edx]          | ecx:EntryPoint
  11. 00401394 | 894D AC                  | mov dword ptr ss:[ebp-54],ecx           | ecx:EntryPoint
  12. 00401397 | 817D AC 40E20100         | cmp dword ptr ss:[ebp-54],1E240         |
  13. 0040139E | 75 16                    | jne crackme.4013B6                      |
  14. 004013A0 | 83C4 F8                  | add esp,FFFFFFF8                        |
  15. 004013A3 | 8D45 B0                  | lea eax,dword ptr ss:[ebp-50]           |
  16. 004013A6 | 50                       | push eax                                |
  17. 004013A7 | 68 70124000              | push <crackme.sub_401270>               | 401270:"\n\t\tGracias por haberte registrado %s"
  18. 004013AC | E8 6F010000              | call <JMP.&printf>                      |

1. Pone en EAX la dirección que utilizará para guardar el serial ( [ebp-54] )

2. Pasa el segundo argumento de la funcíón "scanf" al stack, que será la dirección donde guardará el serial, recordar que EAX contiene la dirección [ebp-54] alias "la dirección donde guarda el serial"
3. Pasa el primer argumento de la función "scanf" al stack, este es un puntero a una String que tiene el formato del dato a recoger, en este caso es "%i", es decir, traerá el serial introducido como un número entero tal cual
4. Llama a la función "scanf" ( scanf("%i",[ebp-54]) ) para recoger el serial introducido, recordar que por los parámetros dados anteriormente, será un número entero y se guardará en la dirección [ebp-54]

5. Acomoda el Stack, no no interesa

6. Toma el contenido de [ebp-54] (el serial) y lo "suma" (add) con 0xFFFFFE0C, el resultado se guarda en el primero operando ( [ebp-54] ). Puse "suma" entre comillas porque en realidad resta, recodar que la representación numérica está restringida al tamaño especificado del operando, es decir, se está haciendo una operación con el DWORD 0xFFFFFE0C que tiene 4 bytes de tamaño, entonces solo permite números positivos que van desde 0x00000001 al 0x7FFFFFFF y los negativos van desde 0x80000000 a 0xFFFFFFFF. El número 0xFFFFFE0C está dentro de la representación de número negativos y equivale a -500 en decimal, hay que realizar la operación correctamente si se usará tal cual en la calculadora:



- De momento tenemos: [ebp-54] = serial + 0xFFFFFE0C

7. Pone en EAX el contenido de [ebp-54] que ahora contiene el resultado de la operación anterior:
EAX =      [ebp-54]
EAX = (serial + 0xFFFFFE0C)


8. Pone en EDX lo que hay en EAX, ahora tenemos tanto en EAX como en EDX el resultado anterior:
EDX =        EAX
EDX = (serial + 0xFFFFFE0C)


9. Suma EDX con EDX y guarda el resultado en EDX:
EDX =        EDX            +        EDX
EDX = (serial + 0xFFFFFE0C) + (serial + 0xFFFFFE0C)


10. Pone en ECX el resultado de sumar EAX y EDX:
ECX =        EAX            +                        EDX
ECX = (serial + 0xFFFFFE0C) + ( (serial + 0xFFFFFE0C) + (serial + 0xFFFFFE0C) )


11. Pone en [ebp-54] el resultado anterior
[ebp-54] = ECX
[ebp-54] = (serial + 0xFFFFFE0C) + ( (serial + 0xFFFFFE0C) + (serial + 0xFFFFFE0C) )


12. Compara [ebp-54] con 0x1E240
13. Si son iguales no salta y se prepara para mostrar el mensaje del "chico bueno"

- Entonces tenemos que hacer sean iguales para que no salte, solo hay que hacer la ecuación y despejarla como en el colegio:

                  0x1E240 = [ebp-54]
                   0x1E240 = (serial + 0xFFFFFE0C) + ( (serial + 0xFFFFFE0C) + (serial + 0xFFFFFE0C) )
                   0x1E240 = (serial + 0xFFFFFE0C) + 2 * (serial + 0xFFFFFE0C)
                   0x1E240 = 3 * (serial + 0xFFFFFE0C)
               0x1E240 / 3 = serial + 0xFFFFFE0C
(0x1E240 / 3) - 0xFFFFFE0C = serial
       0xA0C0 - 0xFFFFFE0C = serial
                    0xA2B4 = serial
                     41652 = serial


- O si lo desean trabajar todo en decimal

           123456 = (serial + (-500)) + ( (serial + (-500)) + (serial + (-500)) )
            123456 = (serial - 500) + ( (serial - 500)) + (serial - 500) )
            123456 = (serial - 500) + 2 * (serial - 500)
            123456 = 3 * (serial - 500)
      (123456 / 3) = serial - 500
(123456 / 3) + 500 = serial
       41152 + 500 = serial
             41652 = serial


---
Referencias:

TEORIA Assembler por CAOS REPTANTE, en la página 5 está el capítulo de Sistemas de Representación, que habla de los números negativos en Hexadecimal:
https://mega.nz/file/JgY0gApa#3zKqcAJm9yrFMzuqqGgdGsVfub5gPsafZhAdHC01L2Q

Informática Básica (2010), en la página 117 "Números con signo" habla de forma detallada la representación de números negativos:
https://repositori.uji.es/bitstreams/9f608796-c3c6-46b0-aa2c-c10da81d685c/download
7  Foros Generales / Dudas Generales / Re: ¿Cómo elimino lo extra de una lista que quiero copiar? en: 18 Septiembre 2025, 01:30 am
No soy muy amigo de Python pero siempre es bueno ejercitarse un poco:

Código
  1. import urllib.request
  2. import re
  3. import os
  4.  
  5. url = 'https://www.nintendolife.com/games/browse?sort=score&system=nes&genre=action'
  6.  
  7. with urllib.request.urlopen(url) as response :
  8.  html = response.read().decode()
  9.  
  10. games = re.findall('<ul class="items cols-4 style-cover">(.*)<nav class="ui-listing-pagination">', html, re.DOTALL)
  11. games = re.findall('<span class="title accent-hover">(.*?)</span>', games[0])
  12.  
  13. with open(os.environ['USERPROFILE'] + '\\Desktop\\games.txt', 'w') as file :
  14.  file.write('\n'.join(games))

Ese código crea en el escritorio un archivo de texto con la lista de juegos, uso dos veces la expresión regular (re) porque a la derecha hay otra lista pero que no entra en el criterio solicitado
8  Foros Generales / Dudas Generales / Re: ¿Cómo elimino lo extra de una lista que quiero copiar? en: 15 Septiembre 2025, 08:52 am
mmm... aparte también está el problema de que las X filas varían XD, creo que lo más fácil es abrir la Consola del Navegador y pegar un Script que extraiga los textos que quieres

Código
  1. var span = document.querySelectorAll("#listing-games span.title")
  2. var txt = ""
  3. for (var el of span) txt += el.textContent + "\n"
  4. console.log(txt)

1. Guarda en la variable span todos los elementos que coincidan con el Selector especificado, en este caso todos los Elementos "span" que tengan la Clase "title" y que estén dentro del Elemento con Id "listing-games"

2. Crea una variable para ir guardando todos los textos de manera legible

3. Un bucle FOR OF que sirve para recorrer cada elemento de la lista de elementos de la línea 1, recoge el contenido de texto del elemento dado y lo guarda en "txt" junto a un salto de línea

4. Imprime el contenido de la variable "txt"



Para entender todo lo anterior requieres javascript + HTML DOM, otra forma más fácil sería usar un programa especializado en extracción de datos muy amigable, por ejemplo PowerBI, las nuevas versiones son horrendamente pesadas y obviamente no serán compatibles con Windows 7, si mal no recuerdo las nuevas versiones de Excel también pueden extraer datos de páginas web pero me parece que tampoco está a tu disposición XD.

Pienso que una versión viejita de PowerBI que justo acabo de probar en un Windows 7 virtual te puede servir, espero que tengas tu Windows 7 actualizado o PowerBI te va a dar problemas, aunque te avisa si falta algo o puedes comentar por acá si manda algún error



Power BI 2.83.5894.961 32-bit julio de 2020
https://web.archive.org/web/20210310063750_/https://download.microsoft.com/download/8/8/0/880BCA75-79DD-466A-927D-1ABF1F5454B0/PBIDesktopSetup-2020-12.exe


Si te pide Internet Explorer 9 mejor instalas el 11, porque yo grabé el video con el 9 y no se ve muy bonita la interfaz, luego probé con el 11 y si se ve mejor, me refiero a esto:



IE 11 para Windows 7 de 32-bit
https://www.microsoft.com/es-ES/download/details.aspx?id=40902

IE 11 para Windows 7 de 64-bit
https://www.microsoft.com/es-ES/download/details.aspx?id=40901
9  Programación / Programación C/C++ / Re: Rechazar espacios en c++ en: 11 Septiembre 2025, 16:13 pm
cin tal cual ignora los espacios, tabulaciones y saltos de línea (Enter) al inicio de lo que se escribe, es decir, si no pones nada y das Enter no pasa nada porque lo ignora, si quieres que no sea ignorado debes usar otra instrucción

Entiendo que estás iniciándote en esto, yo recomiendo siempre un buen libro que detalle el comportamiento de las instrucciones que se usan para entenderlas, por ejemplo:

Fundamentos de Programación con C++
http://www.lcc.uma.es/~vicente/docencia/cppdoc/programacion_cxx.pdf

Revisa la parte de "Entrada y Salida de Datos Básica" ahí lo explica todo, en especial la subparte de "Entrada de Datos"

Normalmente se suele utilizar getline para tomar toda la entrada de datos quitando el Enter final, esto lo puedes ver también en el libro en la sección: "6.2.1. Entrada y Salida de Cadenas de Caracteres"

Para tu ejercicio usando getline sería así:

Código
  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. int main () {
  7.  
  8.  struct datos {
  9.    string nombre;
  10.    int edad;
  11.  };
  12.  datos persona;
  13.  
  14.  //Pide un nombre, y rechaza la opcion cuando se ingresa "p".
  15.  //En vez de "p" debería ingresar un espacio vacío o nada.
  16.  do {
  17.    cout << "Ingrese nombre: ";
  18.    getline(cin, persona.nombre);
  19.  
  20.    if (persona.nombre.compare("") == 0) {
  21.      cout << "No hay nombre." << endl;
  22.    }
  23.  } while (persona.nombre.compare("") == 0);
  24.  
  25.  return 0;
  26. }

Recomiendo leer al completo las dos partes que mencioné porque además de mostrar con ejemplos el uso y comportamiento de cada instrucción también muestra posibles errores del uso de estos o la combinación de estos y como solucionarlos. Esto lo digo porque veo que también vas a pedir la Edad que seguramente lo pedirás con cin, en la página 58 y 59 tienes lo que sería tu ejercicio resuelto usando getline y cin con nombre y edad
10  Programación / Programación General / Re: Excel 2013 indicar celda "contigua" al 2ndo máximo valor, repetible. en: 29 Agosto 2025, 15:26 pm
Citar
Me dijeron una forma más sencilla de hacerlo, básicamente:
=JERARQUIA.EQV(Q124;$Q$124:$Q$138;0)+CONTAR.SI($Q$124:Q124;Q124)-1

JERARQUIA.EQV genera una lista ordenada de mayor a menor (si pones el argumento 0) y te da la posición (en la lista) del valor que le digas:
=JERARQUIA.EQV(valor a buscar;rango en donde buscar;modo)

JERARQUIA.EQV es de las "nuevas" fórmulas que ponen para intentar ser más legibles, como desventaja es que solo funciona con valores numéricos, la fórmula madre CONTAR.SI hace exactamente lo mismo con más lógica, estas dos formulas son completamente equivalentes, aparte de que CONTAR.SI funciona con números y texto:

  A        B          C
 +-----------------------------  
1|     JERARQUIA.EQV   CONTAR.SI
2| 9         1            1
3| 9         1            1
4| 9         1            1
5| 8         4            4


=JERARQUIA.EQV(A2;$A$2:$A$5;0)

=CONTAR.SI($A$2:$A$5;">"&A2)+1

Citar
Luego se le suma las repeticiones que se encuentren hasta la fila en cuestión, restando 1 para que su propio valor no se cuenta. Eso hace que los valores repetidos más abajo tengan más repeticiones que los mismos de arriba, haciendo que el resultado sea mayor.

Pero acabo de notar un posible error... si un valor tiene muchos repetidos le suma mucho y entonces puede que quede con una posición mayor a la que debe, pero por lo que veo eso no ocurre, no sé por qué  :huh:

No hay error porque está usando rangos dinámicos CONTAR.SI($Q$124:Q124;Q124), ves que $Q$124 inmoviliza esa coordenada, pero Q124 no está inmovilizado, por eso al arrastrar la fórmula $Q$124 se mantendrá mientras que Q124 se irá incrementando por cada celda que se arrastre aumentando el rango dinámicamente, el último Q124 es la condición, es decir, cuenta cuantas apariciones del valor último (Q124) hay en el rango dinámico $Q$124:Q124

Teniendo todo lo anterior claro, puedes utilizar:

=CONTAR.SI($A$2:$A$5;">"&A2)+CONTAR.SI($A$2:A2;A2)

---
Otra opción por la que podrías optar es usar Macros, siempre hay gente purista que lo quiere hacer todo con fórmulas madre, otros con fórmulas matriciales, otros todo con tablas dinámicas, otros todo con macros, etc, es una locura XD, pero es bueno conocer un poco de todo.



Con darle click derecho al nombre de la hoja, Ver código abres el editor de macros, arriba tienes el ámbito (General y Worksheet), se elige Worksheet que corresponde a la Hoja actual, luego se elige el evento, se utilizará Change porque este se ejecuta cada vez que hay cambios en alguna celda de la hoja

El código es:

Código
  1. Private Sub Worksheet_Change(ByVal Target As Range)
  2.  Application.EnableEvents = False
  3.  promedios = Range("L131:L137").Value
  4.  ataqueTipos = Range("B131:B137").Value
  5.  For i = 2 To UBound(promedios)
  6.    For j = 1 To UBound(promedios) + 1 - i
  7.      If promedios(j, 1) < promedios(j + 1, 1) Then
  8.        tmp = promedios(j, 1)
  9.        promedios(j, 1) = promedios(j + 1, 1)
  10.        promedios(j + 1, 1) = tmp
  11.        tmp = ataqueTipos(j, 1)
  12.        ataqueTipos(j, 1) = ataqueTipos(j + 1, 1)
  13.        ataqueTipos(j + 1, 1) = tmp
  14.      End If
  15.    Next
  16.  Next
  17.  Range("B127") = ataqueTipos(1, 1)
  18.  Range("B128") = ataqueTipos(2, 1)
  19.  Application.EnableEvents = True
  20. End Sub

1. Indica el tipo de estructura (Private Sub) en este caso es una Procedimiento (función que no devuelve valor), el nombre es Worksheet_Change (puede ser cualquiera, pero el nombre por defecto ya es bastante claro al dar a entender que corresponde al evento Change de la Hoja), luego están los argumentos del Procedimiento, por defecto está el argumento de nombre Target de tipo (As) Range (rango de celdas) y se pasa por valor (ByVal)

2. Esta línea desactiva los eventos, claro, sino cualquier cambio en el Excel volvería a llamar a este Procedimiento, incluso este Procedimiento puede hacer cambios y no queremos que se re-llame, al menos no hasta terminar

3 y 4. Declaro dos variables Array, el primero para guardar los "promedios", y el otro para guardar los "ataques tipos", los Range siempre devuelven Arrays bidimensionales (Fila, Columna), además estos Arrays empezarán con índice 1 en lugar de 0

5 al 16. Es el famoso algoritmo de ordenación Burbuja, los bucles en las Macros de Excel (VBA) tienen diferente sintaxis a las que ya conoces, For inicializar_variable To valor_maximo_de_variable, por ejemplo el clásico for (i = 0; i < 10; i++) en VBA es: For i = 0 To 9, no requiere el i++ porque se sobreentiende que la variable debe aumentar de uno en uno con cada iteración

Ubound devuelve el último índice de un Array, si el Array es: vocales = ("a", "e", "i", "o", "u"), UBound(vocales) devolverá 4 porque se sobreentiende que el array vocales empieza con índice 0:

vocales(0) = "a"
vocales(1) = "e"
vocales(2) = "i"
vocales(3) = "o"
vocales(4) = "u"

Ah, y los Arrays en VBA usan paréntesis en lugar de corchetes como se puede ver. Considerando que Range devuelve un Array bidimensional y que además el primer índice empieza en 1, sería algo así suponiendo que las vocales están en el rango "A1:A5" :

vocales = Range("A1:A5")

Es lo mismo que:

vocales(1,1) = "a"
vocales(2,1) = "e"
vocales(3,1) = "i"
vocales(4,1) = "o"
vocales(5,1) = "u"

Recuerda: vocales(fila, columna), si usas UBound(vocales) devuelve el último índice del array, es decir 5

El Algoritmo de Ordenación es muy popular así que no lo explicaré, salvo las líneas 11, 12 y 13 porque lo que hacen es replicar esa misma ordenación con el Array "ataqueTipos" para replicar esa ordenación, también decir que en todos los casos se está índicando el 1 en por ejemplo promedio(j,1) porque el Array es bidimensional pero como solo tiene una Columna y no necesitamos más, ponemos 1, solo varía la Fila

17 y 18 Escriben el primer y segundo valor del Array ordenado en la celda de resultados

19 Vuelve a activar los eventos

---
Adjunto el archivo de excel para que lo revises, y otra cosa importante de las Macros es que para que se conserven debes guardar el archivo como .xlsm en lugar de .xlsx, el propio excel te lo recordará, aparte de los permisos y confianza en las macros claro, esa es la desventaja de las macros, muy escandalosas

https://mega.nz/file/0wYUwajC#ulsigtqFbg-HURicEbyU8zLyTYgq8dpBN3CWIhE3vYk
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... 237
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines