none
Problema con Redim Preserve RRS feed

  • Pregunta

  • Hola de nuevo... ya estoy dando por saco otra vez. Siento ser pesado...

    Declaro una variable en la clase principal del formulario.

    Dim total(0, 6) As String
    Dim n as integer=0

    Cuando hago Click en un datagridview, necesito algo si:

            n = n + 1
            ReDim Preserve total(n, 6)
    
    
            fila = Me.DGVDeudasPac.CurrentRow()
    
            total(n, 1) = CStr(fila.Cells("numventa").Value)
            total(n, 2) = CStr(fila.Cells("deuda").Value)
            total(n, 3) = CStr(fila.Cells("tipo").Value)
            total(n, 6) = CStr(fila.Cells("concepto").Value)
            total(n, 5) = CStr(fila.Cells("iva").Value)

    Cada vez que haces click, necesito redimensionar el array, pero el de la izquierda, y preserve unicamente me permite redimensionar el último de la derecha... no se me ocurre como hacer esto...

    Lo necesito para luego hacer unos update e insert e varias tablas con un for e ir recorriendo ese array.
    Una opción un poco chapucera sería declarar el array asi:

    Dim total(20, 6) As String
    Pero me parece un poco chapuza...no?

    sábado, 19 de octubre de 2019 11:26

Respuestas

  • Hay otra solución más sencilla: intercambia el primer índice y el segundo en todos los sitios donde los uses en el programa.

    Por ejemplo, si usas total(a,b) cámbialo por total(b,a). Haz esto en todos los sitios donde se use la variable "total" (puedes encontrarlos fácilmente usando la opción de "buscar todas las referencias" en Visual Studio).

    Después de hacer ese cambio, ya puedes redimensionar fácilmente el array, porque ahora el índice que tienes que redimensionar es el de la derecha.

    Ahora bien, dicho eso, yo te recomendaría buscar otra alternativa. En VB.NET el Redim Preserve tiene muy mal rendimiento. La razón es que en .NET los arrays son inmutables, no pueden cambiar de tamaño una vez creados. Entonces lo que hace el Redim Preserve es crear un nuevo array con la nueva dimensión, copiar todos los datos del antiguo array al nuevo, y destruir el antiguo. Si solo tienes 20 registros no se notará mucho, pero si tienes "miles", verás que la lectura de todos los registros se vuelve muy lenta. Por eso cuando se leen datos en un bucle y hay que irlos guardando sobre la marcha y no se sabe de antemano cuántos hay, es mucho más usual usar un List(Of T) u otra clase similar, en lugar de usar un array.

    sábado, 19 de octubre de 2019 16:05

Todas las respuestas

  • Hay otra solución más sencilla: intercambia el primer índice y el segundo en todos los sitios donde los uses en el programa.

    Por ejemplo, si usas total(a,b) cámbialo por total(b,a). Haz esto en todos los sitios donde se use la variable "total" (puedes encontrarlos fácilmente usando la opción de "buscar todas las referencias" en Visual Studio).

    Después de hacer ese cambio, ya puedes redimensionar fácilmente el array, porque ahora el índice que tienes que redimensionar es el de la derecha.

    Ahora bien, dicho eso, yo te recomendaría buscar otra alternativa. En VB.NET el Redim Preserve tiene muy mal rendimiento. La razón es que en .NET los arrays son inmutables, no pueden cambiar de tamaño una vez creados. Entonces lo que hace el Redim Preserve es crear un nuevo array con la nueva dimensión, copiar todos los datos del antiguo array al nuevo, y destruir el antiguo. Si solo tienes 20 registros no se notará mucho, pero si tienes "miles", verás que la lectura de todos los registros se vuelve muy lenta. Por eso cuando se leen datos en un bucle y hay que irlos guardando sobre la marcha y no se sabe de antemano cuántos hay, es mucho más usual usar un List(Of T) u otra clase similar, en lugar de usar un array.

    sábado, 19 de octubre de 2019 16:05
  • Hola Alberto,

    Gracias por tu ayuda y consejos.

    Normalmente el array tendrá estas dimensiones total(1,6)... Esto esta en la opcion de cobrar unas deudas, por lo que normalmente solo cobrarán 1, pero doy la opción que cobren mas... No creo que nadie cobre mas de 5 la verdad... que sería total(5,6) por lo que no creo que esto se vuelva muy lento, pero tomo nota de todo lo que comentas!

    No obstante voy a porbarlo con por ejemplo total(10,6) a ver que lento se vuelve y me voy a informar sobre List(Of T), que me suena haberlo visto pero nunca lo usé...

    Como siempre gracias por tu tiempo y tus consejos!

    Un saludo

    lunes, 21 de octubre de 2019 8:33
  • Finalmente se me ha ocurrido otra idea, como se el número de registros(de ventas) que tiene para cobrar... lo tengo guardado en un Datatable, miro los registros que hay y así inicializo el array correctamente... y al finalizar borro el array.
    Creo que estaría bastante bien así.

    Un saludo.

    lunes, 21 de octubre de 2019 9:26
  • Sí, efectivamente así está bien. Fíjate en que la respuesta que yo te di mencionaba expresamente "[...] cuando se leen datos [...] y no se sabe de antemano cuántos hay [...]". Pero si sabes el número que hay, como acabas de decir, entonces las cosas son mucho más sencillas porque puedes dimensionar de antemano el array al tamaño correcto, y no hay que redimensionar nada.
    lunes, 21 de octubre de 2019 9:39