Páginas (2): 1 2   
Grandamakulo   17-03-2025, 13:40
#1
Hola, compañeros:
Me temo que no he sido capaz de explicar convenientemente el problema en el título del tema. En realidad, es que no es sencillo de explicar. Vayamos por partes, como dijo Jack.
Defino una estructura en un formulario y tres matrices —en realidad, vectores, pero vamos, no nos pongamos quejicosos—:

Código:
Public Struct struCampos
  Nombre As String              '?[0] Nombre en el programa de la columna ¿Quitar?'
  Texto As String              ' [1] Título de la columna, traducible'
  Tipo As String                ' [2] Cualquiera de los cuatro tipos posibles'
  Contenido As Variant          ' [3] Contenido por defecto para la columna:'
                                '    * Para texto: texto plano'
                                '    * Para listas:'
                                '      ?[0] índice entero ¿Quitar?'
                                '      [1] texto plano'
                                '      [2] color papel'
                                '      [3] color tinta'
                                '    * Para fechas: a definir'
  Color As Integer              ' [4] Color de fondo para toda la columna'
  ' NOTE: Aquí añadir gestión de fondos definiendo una banderita de auto'
  Resaltar As Boolean          ' [5] ¿Se resaltan los contenidos de esta lista?'
End Struct

Public $cFijos As New StruCampos[]          ' Campos obligatorios'
Public $cRemanentes As New StruCampos[]    ' Campos definidos no mostrados'
Public $cUsados As New StruCampos[]        ' Usados o visibles en columnas'

—Olvidémonos de los comentarios y de las malas praxis con los nombres, por el momento Smile —.
Inserto algunos elementos vacíos, pero les cambio la propiedad .Nombre:

Código:
  For i = 0 To lsoRemanentes.Count - 1
    Dim cDos As New StruCampos
    $cRemanentesP.Add(cDos)
    $cRemanentesP.Last.Nombre = lsoRemanentes[i].Text
  Next

Y resulta que siempre añade el mismo, es decir, cuando exploro la matriz todos, absolutamente todos los elementos son el mismo, en concreto, el último que he pasado.

Además, si se me ocurre pasar estas matrices entre formularios, por ejemplo:

Código:
  $cRemanentesP = FPral.$cRemanentes
  $cUsadosP = FPral.$cUsados
  $cFijosP = FPral.$cFijos

Resulta que pasa las matrices por referencia, no por valor, por lo que me las modifica en el origen. Es decir, si hago $cFijosP en el nuevo formulario para trabajar y después ver si hago los cambios definitivos y los paso o no a FPral.$cFijos, resulta que no, porque modifica ambas matrices como si fuesen la misma. 
Estoy convencidísimo que es una auténtica chorrada, pero mi torpeza e ignorancia me impide verlo. en fin, a ver si algún alma caritativa me ilumina. ¡Y muchas gracias de antemano!
Última modificación: 19-03-2025, 09:50 por Grandamakulo.

En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
Shordi   17-03-2025, 18:47
#2
He intentado manejar tu código, pero no he sido capaz de hacerlo funcionar. Sube un pequeño proyecto simplificado que reproduzca ese comportamiento y te podré ayudar.
Por otro lado, yo cambiaría esto:
Código:
  For i = 0 To lsoRemanentes.Count - 1
    Dim cDos As New StruCampos
    $cRemanentesP.Add(cDos)
    $cRemanentesP.Last.Nombre = lsoRemanentes[i].Text
  Next
Por esto:
Código:
Dim cDos As New StruCampos
 
For i = 0 To lsoRemanentes.Count - 1
    cDos=new StruCampos 
   cDos = lsoRemanentes[i].Text
    $cRemanentesP.Add(cDos)
Next
Pero sin poder probarlo no sé si te sirve de algo el consejo.

Saludes

No podemos regresar
Grandamakulo   17-03-2025, 19:47
#3
¡Perfecto!, a tu código solo le he cambiado cDos.Texto = lsoRemanentes[i].Text. Ahora me queda lo del cambio de matrices. Voy  a ver si soy capaz de hacer un miniejemplo y pasarlo.

En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
guizans   17-03-2025, 22:09
#4
No he probado tu código Shordi, pero veo algo raro que me llama mucho la atención y debería estar mal según mi opinión. El la primera línea creas una variable cDos como StruCampos y la instancias con New. Y después dentro del bucles vuelves a instanciar la variable cDos, ¿Esto es correcto? Es que me chirria mucho.
Grandamakulo   17-03-2025, 23:39
#5
(17-03-2025, 22:09)guizans escribió: No he probado tu código Shordi, pero veo algo raro que me llama mucho la atención y debería estar mal según mi opinión. El la primera línea creas una variable cDos como StruCampos y la instancias con New. Y después dentro del bucles vuelves a instanciar la variable cDos, ¿Esto es correcto? Es que me chirria mucho.

La verdad es que lo he probado, y ha funcionado perfecto.

En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
Shordi   18-03-2025, 09:53
#6
(17-03-2025, 22:09)guizans escribió: No he probado tu código Shordi, pero veo algo raro que me llama mucho la atención y debería estar mal según mi opinión. El la primera línea creas una variable cDos como StruCampos y la instancias con New. Y después dentro del bucles vuelves a instanciar la variable cDos, ¿Esto es correcto? Es que me chirria mucho.

No sé si es correcto. Como digo, al no poder reproducir el código de Grandamakulo, no sé si funcionaría sin el New dentro del Dim. Pero sí estoy seguro de que funcionaría con él.
Explicación:
El problema, tal como yo lo veo, es que si incluyes el Dim, es decir la asignación de la ubicación en memoria, en el bucle, el compilador utilizará siempre la misma dirección que para él estará "limpia" (Explicación estúpida porque no tengo ni puta idea de qué hace exactamente el compilador con el Dim). Sin embargo, si declaras la variable fuera del bucle, y queda declarada, cada "New" implicará una nueva dirección de memoria, es decir un objeto nuevo.

Si Grandamakulo quiere, que pruebe sin el New en la declaración y nos saca de dudas.

Saludos

Por cierto, he notado que cuando subimos código, al encontrar el caracter ' de los comentarios se pone toíto coloraíto hasta que encuentra otro ' . Habrá que "Abrir y Cerrar" los comentarios para que quede más mono...
Última modificación: 18-03-2025, 09:57 por Shordi.

No podemos regresar
Grandamakulo   18-03-2025, 12:46
#7
Resumen ejecutivo:
Con New funciona.
Sin New no funciona.

Matizando. Efectivamente, con New funciona perfectamente. Sin New no asigna un «espacio nuevo» —yo aquí me limito a parafrasear a @Shordi, porque mi ignorancia se exacerba cosa mala—, y el resultado es que todos los valores son el último.

PS.—Tomo nota de lo del cierre de comillas.

A ver, aquí añado un miniejemplo que muestra tanto lo del New como el problema que tengo con las matrices —insisto, seguro que es una tontería—.
.gz
prueba-paso-de-matrices.tar.gz (Tamaño: 18.16 KB Descargas: 2)
Última modificación: 18-03-2025, 13:23 por Grandamakulo.

En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
Shordi   18-03-2025, 13:51
#8
Respecto a lo del New, el new que hay que eliminar el el de la declaración:

Dim Anhadir As New MiTipo

si lo dejas en

Dim Anhadir As MiTipo

Sigue funcionando bien. Guizan tenía razón y sobraba. Error mío (pero no volveré a pedir perdón porque "Un anciano nunca se disculpa dos veces". Maestro Po. Serie televisión Kung-Fú capítulo 1)

Respecto a la pasa por referencia no es un problema de referencias es un problema de ámbitos. Declaras:

Private Pasada As New MiTipo[]

Eso otorga una vida y visibilidad a MiTipo relativa al formulario, con lo que el FMain ni se entera. Cambia a

Public Pasada As New MiTipo[]

y te funcionará bien.

Saludos.
Última modificación: 18-03-2025, 13:52 por Shordi.

No podemos regresar
Grandamakulo   18-03-2025, 14:32
#9
Lo de New, perfecto. Listo y funcionando.

Pero lo de las matrices, sigue ocurriendo. Esto es, declaro la matriz primaria en FMain, la leo desde Form1 y la paso a la secundaria. Modifico la secundaria y, sin hacer nada más, la primaria automáticamente cambia para ser igual que la secundaria. No sé si me he explicado:

FMain: A=Valor1

Form1: B=A
Form1: B=Valor2
Form1: automáticamente ¡A=B!

Y esto, independientemente del ámbito de B. A, claramente, debe ser pública
Última modificación: 18-03-2025, 14:33 por Grandamakulo.

En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
Shordi   18-03-2025, 15:26
#10
Ah... Lo había entendido al revés. Está tarde te lo miro. Después de la obligatoria siesta española, claro.

Slaudos

No podemos regresar
Páginas (2): 1 2   
  
Usuarios navegando en este tema: 1 invitado(s)
Powered By MyBB, © 2002-2025 MyBB Group.
Made with by Curves UI.