** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Access y VBA
  Mensajes nuevos Mensajes nuevos RSS - como grabar una matriz en una tabla
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Tema cerradocomo grabar una matriz en una tabla

 Responder Responder Página  <12
Autor
Mensaje
01loko Ver desplegable
Colaborador
Colaborador


Unido: 17/Agosto/2017
Localización: Santander
Estado: Sin conexión
Puntos: 807
Enlace directo a este mensaje Enviado: 07/Abril/2020 a las 19:51
Yo (que no suelo usar matrices, principalmente por falta e conocimientos) en una ocasion y con 62 campos, lo que hice fue crear una tabla con el nombre de los campos la recorria a la vez que rellenaba su valor desde, en ese caso, un fichero texto.

si os interesa, tengo por algun lado el codigo usado

Recordar de que soy nuevo y estoy aprendiendo.
Arriba
guarracuco Ver desplegable
Moderador
Moderador


Unido: 24/Abril/2004
Localización: EEUU
Estado: Sin conexión
Puntos: 3239
Enlace directo a este mensaje Enviado: 07/Abril/2020 a las 21:39
Se puede recorrer una matriz bidimensional, sin necesidad de posarte en cada columna, solo tomando la línea completa.
Arriba
Dabellaso Ver desplegable
Asiduo
Asiduo


Unido: 18/Noviembre/2012
Localización: España
Estado: Sin conexión
Puntos: 338
Enlace directo a este mensaje Enviado: 07/Abril/2020 a las 22:22
Leyendo a guarracuco, se me ocurre que, si como dice kkodlton al inicio, su matriz bidimensiona al ser A(500000,50), indica que son 500000 registros, con 50 valores (para 50 campos).

En ese caso atendiendo a guarracuco, sólo tendríamos que recorrer la dimensión de los registros, para obtener, tanto los registros como los datos.

En cada vuelta de cada registro, un For i obtiene los valores de los campos para ese registro.

 

Dim i As Long
Dim x  As Long
Dim dbs As DAO.Database
Dim tabla As DAO.TableDef
Dim campo As DAO.Field
Dim strListaCampos As String
Dim strListaValores As String

    Set dbs = CurrentDb
    Set tabla = dbs.TableDefs("MiTabla")
    
    For Each campo In tabla.Fields 'Para recorrer los campos existentes en la tabla
        strListaCampos = strListaCampos & IIf(strListaCampos = "", "", ",") & campo.Name
    Next campo
    
     For x = LBound(mtz, 1) To UBound(mtz, 1) 'Si la matriz es de la forma (50000,50) recorreremos los 50000 ítems que supongo serán los registros
    
'            strListaValores = Join(mtz, ",") 'No uso Join por que sólo funciona con matrices unidimensionales
                        'no conozco modo de indicarle la dimension de la que queremos que tome los valores a unir

        For i = LBound(mtz, 2) To UBound(mtz, 2) 'Para recorrer la dimensión núm.2 (La de los valores, que según la matriz (50000,50) serán 50 vueltas)
'           De este modo obtenemos los 50 valores de los 50 campos del registro actual (x)
                    
            strListaValores = strListaValores & IIf(strListaValores = "", "", ",") & "'" & CStr(mtz(x, i)) & "'"
            
        Next i
        i = 0 'reiniciamos i, para la próxima vuelta de x
        
        'En este punto, a cada vuelta de i (A cada registro de los 50000, ya tendremos los 50 nuevos valores para cada campo de cada registro)
        'Creamos el registro
    CurrentDb.Execute ("INSERT INTO MiTabla (" & strListaCampos & ") VALUES (" & strListaValores & ");")

    
    Next x

 


Que os parece?
Si es eso intentare leer mejor la pregunta la próxima vez antes de responder LOL


Editado por Dabellaso - 07/Abril/2020 a las 22:24
El saber no ocupa lugar, sólo tiempo
Arriba
kkodalton Ver desplegable
Nuevo
Nuevo
Avatar

Unido: 01/Diciembre/2011
Localización: España
Estado: Sin conexión
Puntos: 32
Enlace directo a este mensaje Enviado: 08/Abril/2020 a las 07:51
Hola
Todavia no he tenido tiempo de mirarme el primero ,y ya tengo otro
Gracias
Arriba
kkodalton Ver desplegable
Nuevo
Nuevo
Avatar

Unido: 01/Diciembre/2011
Localización: España
Estado: Sin conexión
Puntos: 32
Enlace directo a este mensaje Enviado: 08/Abril/2020 a las 08:56
Hola de nuevo

Gracias a todos, empiezo a tener mucha información y ya no se con cual me quedare, lo he de probar. De hecho todavía no tengo hecha ni la matriz, pero me encontraba con ese primer escollo que no sabia como hacerlo.

La tabla que necesito crear no depende de ningun formulario con lo cual los nombres de los campos los puedo cambiar. Mihura me recomiendas que los nombres no empiecen por un numero y así me evitare muchos problemas, esto ya me ha pasado y lo he tenido que cambiar, pero podrías explicarme el motivo?
Podria poner los nombres de los campos como tu digas y después de hacer todo el proceso para grabarla nueva tabla  renombrarlos para que sean mas claros para mi, verdad?


Guarracuco, me podrias explicar que significa y que haría esto:
Yo creia que el join solo existia en una consulta sql ...

For i=0 to ubound(arreglo)
StrSql=join(arreglo(i), ",")
Currentdb.execute "insert into Tutabla " . StrSql

De hecho mi tabla inicial  tiene n registros , donde un mismo usuario tiene m registros dentro de esa tabla. Mi intención es crear una nueva tabla de referencias cruzadas, tipo graella.
Si en la tabla inicial tuviera ya los valores de los 50 campos, esta claro que haciendo una tabla de referencias cruzadas solucionaria el problema, pero hay campos vacíos que los tengo antes que rellenar, de hecho para los campos vacíos los relleno con el valor anterior del campo anterior.
Por ese motivo había pensado en crear una matriz y así cuando ya halla introducido todos los valores en una matriz unidimensional grabar el resultado en una tabla.

Espero haberos aclarado más la situación y muchísimas gracias por todo.



Arriba
Mihura Ver desplegable
Administrador
Administrador
Avatar

Unido: 06/Mayo/2005
Localización: En la dehesa
Estado: Sin conexión
Puntos: 13990
Enlace directo a este mensaje Enviado: 08/Abril/2020 a las 09:28
“si Mihura tiene la bondad” LOL, por cierto al principio de los tiempos era sin la h, pero esta me la incluyó un profe de literatura … pero bueno eso es otra historia.

El no poner números por delante (o blancos entremedias, o caracteres especiales) es que VBA no puede referenciar esos campos directamente (hay que encerrarlos entre corchetes), en los formularios lo mismo, etc … es decir, te creas muuuuucho trabajo gratis, … mejor que no.

Cuando se hace una instrucción SQL, ya sea INSERT INTO, SELECT, DELETE, …. Access realiza una apertura de la tabla (recordset, colección de datos) que va a tratar, el proceso que hemos pedido y un cierre de la misma. Si lo tratamos con un recordset hacemos los mismo: una apertura, el proceso y un cierre del mismo.
- si tratamos un registro los procesos son los mismos y los tiempos de ejecución son los mismos, 
- pero sin tratamos muchos registros la cosa cambia, supongamos los 50.000 de los que hablamos en el hilo, si lo hacemos con SQL hay 50.000 aperturas, 50.000 inserciones de registro y 50.000 cierres, en cambio con un recordset hay una apertura, 50.000 inserciones y un cierre
Se nota y mucho.

El proceso con recordset (esquemático y sin comprobar) sería:
Dim Rs as DAO.Recordset

Set Rs = Currentdb.OpenRecordset(“Mitabla”,,dbappendonly)
For i = 1 to 50.000
    Rs.Addnew
    Rs!Campo = …
    …
    Rs.Update
Next
Rs.Close


En cuanto a la definición de campos me gustaría que nos dijeses que es lo que quieres guardar y que es lo que quieres obtener, … por lo que ‘entreveo’ son datos anuales (desglosados mes a mes), ¿es correcto? ¿son 50 campos ahora, pero que serán 60 dentro de tres meses? ¿serán fijos? … me falta información para seguir adelante con el diseño

Jesús Mansilla Castells.
Saludos desde Móstoles.

Access Aplicaciones
Tecsys.es
Arriba
kkodalton Ver desplegable
Nuevo
Nuevo
Avatar

Unido: 01/Diciembre/2011
Localización: España
Estado: Sin conexión
Puntos: 32
Enlace directo a este mensaje Enviado: 08/Abril/2020 a las 11:54
Hola

Si Mihura , son datos anuales desglosados mes a mes. Seran fijos o no? yo diria que puede ser las dos cosas. Es mas rapido para mi que no sean fijos, asi ejecuto y tengo la tabla actualitzada. Tambien podria hacer que a partir de una primera tabla crear una nueva, no se.
Este ultimo proceso que has añadido, me gusta a medias.. porque eso significa que he de ir nombrando los 50 campos?, por eso pense en la solucion de la matriz
Arriba
Mihura Ver desplegable
Administrador
Administrador
Avatar

Unido: 06/Mayo/2005
Localización: En la dehesa
Estado: Sin conexión
Puntos: 13990
Enlace directo a este mensaje Enviado: 08/Abril/2020 a las 13:00
Si son datos anuales yo me crearía una tabla con el siguiente formato:

TDatos:
Id -> autonumerico
Codigo -> ¿String? ¿Numerico?. Codigo que te identifique el tipo dato que vas a guardar
Ano -> Long
Mes01 -> Double (enero)
Mes02 -> Double (febrero)
..
Mes12 -> Double (diciembre)



El tratamiento ya depende de cómo lo vayas a mostrar en el formulario/informe.

Para pasar los datos a esa matriz basta con un bucle:

for i = 1 to 12
Matriz(i) = Rs("Mes" & format(i, "00"))
Next

Y al contrario para pasar de la matriz al campo del recordset.


Esto mismo valdría para pasar campos con un formulario, suponiendo que los campos se llamen igual:
    Forms("MiFormulario").Controls("Mes" & format(i, "00")) = Rs("Mes" & format(i, "00"))
o:
    Me.Controls("Mes" & format(i, "00")) = Rs("Mes" & format(i, "00"))



Otra opción de diseño sería:

TDatos:
Id -> autonumerico
Codigo -> ¿String? ¿Numerico?. Codigo que te identifique el tipo dato que vas a guardar
Ano -> Long
Datos -> memo

En el campo Datos se guardarían todos los datos que se necesiten separados por un separador (valga la redundancia) -yo uso la pleca |-, entonces al leer obtienes los datos con un simple split:
Matriz = Split(Datos, "|")

y lo guardas con un Join:
Rs("Datos") = Join(Matriz, "|")





Editado por Mihura - 08/Abril/2020 a las 13:02
Jesús Mansilla Castells.
Saludos desde Móstoles.

Access Aplicaciones
Tecsys.es
Arriba
kkodalton Ver desplegable
Nuevo
Nuevo
Avatar

Unido: 01/Diciembre/2011
Localización: España
Estado: Sin conexión
Puntos: 32
Enlace directo a este mensaje Enviado: 17/Abril/2020 a las 10:51
Hola de nuevo

Intente hacerlo con matrices per no me salia, por lo que al final opte por hacerlo con 2 recordset, uno para coger los datos y otro para grabar en la tabla final.

Respecto a los nombres de los campos que me insistiais mucho en que incluyeran un orden, yo en el procedimiento no los he utilizado, en su lugar para referirme a ellos añadia el valor correspondiente en la posicion deseada (campo deseado) , utilizando este formato:

rs1.Fields(x).Value


La tabla resultante ha sido de 33 campos con 400.000 registros, y ejecutarlo solo ha tardado 4 minutos, con lo cual creo que debe ser eficiente.

Quiero añadir que gracias a vuestros comentarios se me ha encendido la luz y he podido acabar el proyecto.

Ahora que me ha salido , me siento muy satisfecho.
Arriba
 Responder Responder Página  <12
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable