Páginas (2): 1 2   
Shell   16-03-2025, 14:01
#1
Buenas!.

Quizás deba mejor mostrar esto en el foro de bases de datos. Huh

He creado un ejemplo para mostrar las tablas de una base de datos y sus registros.
Se puede seleccionar el archivo en concreto y ver en un GridView como es la tabla en cuestión.

[Imagen: 6lmePEHl.png]

He probado con distintos archivos de distintos tamaños.

¿ Qué hacéis cuando la base de datos es enorme ?.

En este ejemplo observo dos cosas. Imaginar una base de datos que contiene muchos registros.
A la hora de seleccionar en el combobox la tabla en concreto,si esta tiene muchos registros hay una demora,
en mostrar el nombre de la tabla tanto en el combobox como en el gridview.

El efecto es, ves la lista de tablas en el combobox, seleccionas y hasta que no se muestra la tabla en el gridview
no se muestra el nuevo cambio de item en el combobox.

He probado con un base de 40K registros y se nota. Siempre se nota esto si la base contiene muchos registros.
He probado con la base de los libros que se ha compartido por febrero. Esta tiene tres tablas, hay una que
se llama "fondo" que en este ejemplo le cuesta muuuuucho mostrar, se muestra el reloj varias veces y desistí.

 ¿ Cómo solucionáis esas situaciones ?

Estamos hablando de que la tabla fondos de la base libro tiene alrededor de 300K registros... Rolleyes


Ah, no he añadido ordenar las columnas. Estoy usando el evento Data para mostrar los registros en el gridview.
Sobre todo si son muchos.


Para el retardo del cambio de item a mostrar en el combobox he usado esto:


Código:
Public Sub cmbTablas_Click()

  Wait 0.1
  MostrarTablaEnGridView(cmbTablas.Current.Text)

End

Eso parece funcionar, otra es muy distinta el tiempo que se tarde en mostrar los registros en el GridView

Saludos

1:50'' para mostrar la tabla Fondos.
Archivos adjuntos
.gz
EjemploBrowserBaseSqlite-0.0.1.tar.gz (Tamaño: 10.56 KB Descargas: 2)
Última modificación: 16-03-2025, 14:54 por Shell.

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Shordi   16-03-2025, 20:37
#2
He visto tu código y lo he probado con 1.000.000 de registros. Tarda la vida entera. Le he echado un vistazo y es una pequeña tontería:
Haces esto para construir el gridview:

Código:
  For Each HRsf In HResul.Fields
    grdTabla.Columns[columna].Text = HRsf.Name
    columna += 1
  Next

  grdTabla.Rows.Count = HResul.Count   'Le metemos un millón de filas

  For columna = 0 To grdTabla.Columns.Count - 1
    grdTabla.Columns[columna].Width = -1  ''Asignamos el ancho de columnas que tienen un millón de filas
  Next

Si cambias de lugar la línea donde asignas el número de filas:

Código:
  For Each HRsf In HResul.Fields
    grdTabla.Columns[columna].Text = HRsf.Name
    columna += 1
  Next

  For columna = 0 To grdTabla.Columns.Count - 1
    grdTabla.Columns[columna].Width = -1
  Next

  grdTabla.Rows.Count = HResul.Count

Te correrá infinitamente más. Por otra parte, no es buena política asignar -1 en gridviews de ancho variable como es el caso porque ese ancho se calcula según el ancho del título y no se altera si el gridview aumenta su tamaño. Tampoco tiene mucho sentido hacer dos bucles recorriendo las columnas, si lo haces así:
Código:
  For Each HRsf In HResul.Fields
    grdTabla.Columns[columna].Text = HRsf.Name
   grdTabla.Columns[columna].Expand = True
    columna += 1
  Next

  grdTabla.Rows.Count = HResul.Count
Matas dos pájaros de un tiro.

Por último una pequeñez, pero que también enlentece algo: En el evento Data utilizas la propiedad .Data, que es una referencia a la celda activa, pero eso requiere de más trabajo porque antes de saber y asignar el texto hay que buscarlo dentro del objeto. Usa la referencia directa a la celda (que para eso se facilitan las coordenadas row y column) y se ejecuta unas tres veces más rápido... aunque quizá no se perciba al ser un evento interactivo con el usuario.

Corrección: con el método .Data tarda muuucho menos que con la referencia de row, column. Había confundido los archivos .prof del perfilador. O sea que no le toques al evento Data.

Así con algo más de un millón de registros me tarda menos de un segundo en actualizar el gridview al seleccionar la tabla.

Saludos

Estoy planeando hacer un vídeo con tu programita para ilustrar la aceleración de los gridviews. ¿Me das permiso para adjuntar tu código al vídeo?

Saludos
Última modificación: 16-03-2025, 21:36 por Shordi.

No podemos regresar
Shell   16-03-2025, 23:56
#3
Gracias Shordi.

Que diferencia!.

(16-03-2025, 20:37)Shordi escribió: Estoy planeando hacer un vídeo con tu programita para ilustrar la aceleración de los gridviews. ¿Me das permiso para adjuntar tu código al vídeo?

Naturalmente, todo lo que ayude con Gambas es bueno para todos. Smile

He intentado usar el método expand  poniéndolo a True, ademas añadí en la propiedad
.autoresize del gridview a True y no se ajusta bien el tamaño de la columna.

Lo estoy probando con la base que comente del ordenador ZxSpectrum y si uso el método expand
la columna de los nombres de los programas queda así:

[Imagen: 2z3wclVl.png]

El tipo de title es varchar y su ancho es de 250

Código:
With grdTabla
    .Columns.Count = HResul.Fields.Count
    .Header = .Both
    .Mode = Select.Single
    '.AutoResize = True
  End With

  For Each HRsf In HResul.Fields
    grdTabla.Columns[columna].Text = HRsf.Name
    'grdTabla.Columns[Columna].Expand = True
    grdTabla.Columns[columna].Width = -1
    columna += 1
  Next
Huh

Si uso -1 en el ancho:

[Imagen: DIOxjp5l.png]

Según la ayuda de Gambas:  El método expand puesto a True:

Cita:Devuelve o establece si una columna de GridView se expande automáticamente para ajustarse al ancho de GridView.
Si la propiedad AutoResize de GridView no está establecida, esta propiedad no tiene efecto, ya que no se produce un ajuste de tamaño automático.

Solo se produce un ajuste de tamaño explícito. Si AutoResize está establecido, entonces:

Si ninguna columna visible tiene la propiedad Expandir establecida, la última columna se expande como si la tuviera establecida. De lo contrario, la diferencia entre el ancho visible y el ancho de las columnas estáticas (sin Expandir establecido) se comparte entre las columnas expandidas.

Si una columna con Expandir establecido tiene un ancho explícito, este ancho explícito se convierte en su ancho mínimo y se tiene en cuenta al compartir el espacio restante.

Y sobre la propiedad .Width y usar -1 dice:

Cita:Devuelve o establece el ancho de la columna. El ancho máximo es 1024. Si establece un ancho negativo, la columna se ajustará automáticamente para ajustarse a su contenido. Solo se tienen en cuenta las primeras mil líneas para calcular el ancho ideal.

Parece que solo lo hace con las primeras 1000 líneas solo.

En su día creo que usaba el tipo font y calculaba entre el ancho de la columna y el ancho del texto que usaba esa fuente.
creo que lo llegué a usar con el evento Data, en este trozo de código no:

Código:
Public Sub MostrarEnGrid(lista As Collection)

  Dim elemento As String
  Dim fila As Integer
  Dim f As New Font

  f.Name = "Sans"
  f.Size = 10

  For Each elemento In lista
    grdEstadistica.Rows.Count = fila + 1
    If grdEstadistica.Columns[0].Width < f.TextWidth(lista.Key) Then grdEstadistica.Columns[0].Width = f.TextWidth(lista.key)
    grdEstadistica[fila, 0].Text = lista.Key
    grdEstadistica[fila, 1].Text = lista[lista.Key]
    fila += 1
  Next

End
Última modificación: 17-03-2025, 00:55 por Shell.

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Shell   17-03-2025, 01:11
#4
¿ Y si hiciera algo como esto ?

Pero declarando la fuente fuera del evento Data claro.

Código:
Public Sub grdTabla_Data(Row As Integer, Column As Integer)

  Dim fuente As New Font

  With fuente
    .Name = "NotoSans"
    .Size = 10
  End With

  HResul.MoveTo(Row)
  grdTabla.Data.Text = HResul[grdTabla.Columns[Column].Text]

  If grdTabla.Columns[Column].Width < fuente.TextWidth(grdTabla.Data.text) Then
    grdTabla.Columns[Column].Width = fuente.TextWidth(grdTabla.Data.text)
  Endif

End
Última modificación: 17-03-2025, 01:11 por Shell.

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Shordi   17-03-2025, 10:54
#5
No hace falta liarse tanto, simplemente activa la propiedad WordWrap del gridview a True y se comportará como las tablas de HTML, es decir, ampliará el alto de la fila para que quepa el contenido cuando sea necesario. Más simple y elegante...

Saludos

No podemos regresar
Shell   17-03-2025, 17:10
#6
WordWrap no ajusta el ancho. Eso hay que verlo mejor. Aunque fuese a lo alto que no se deformase.

Este método me ha resultado mejor.
Sin usar expand ni -1 en el ancho de la columna

Código:
Public Sub grdTabla_Data(Row As Integer, Column As Integer)

  HResul.MoveTo(Row)
  grdTabla.Data.Text = HResul[grdTabla.Columns[Column].Text]
  'Si el ancho del texto es mayor que al ancho de la columna
  If grdTabla.Font.TextWidth(grdTabla.Data.Text) > grdTabla.Columns[column].Width Then
    'Ajusta el ancho de la columna al ancho del texto con un pequeño margen de un caracter
    grdTabla.Columns[column].Width = grdTabla.Font.TextWidth(grdTabla.Data.Text) + grdTabla.Font.TextWidth(" ")
  Endif

End

En concreto hay títulos de juegos que son exageradamente largos, pero son menos:

Como este y ademas puede que sea hasta gracioso.  Rolleyes

[Imagen: zPXZ6JJl.png]

Atención a la traducción:
Cita:Tenía una cabeza tan grande que si fuera un gato tendría que tirar los ratones de debajo de la cama con una ceja

Lo cierto es que no ha perdido rendimiento con ese método y la base de los libros.


Saludos

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Grandamakulo   17-03-2025, 17:15
#7
(17-03-2025, 10:54)Shordi escribió: No hace falta liarse tanto, simplemente activa la propiedad WordWrap del gridview a True y se comportará como las tablas de HTML, es decir, ampliará el alto de la fila para que quepa el contenido cuando sea necesario. Más simple y elegante...

Saludos

Creo, en mi infinita zotez, que, además del .Wordwrap, se debe poner el .Rows[k].High = -1.

En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
Shordi   17-03-2025, 18:52
#8
Efectivamente ha sido un lapsus mental de un servidor mientras hacía el vídeo (las cosas del directo). En realidad la solución que yo encontré al alto de fila hace un siglo era éste:

Código:
Public Sub grid_Data(row As Integer, col As Integer)

    If $source.count = 0 Then Return
    Try Me[row, col].RichText = $source[row][col]
    Me[row, col].WordWrap = $wordWrap
    If $wordWrap Then Me.Rows[row].Height = Max(Me.Rows[row].Height, Me[row, col].Font.RichTextHeight(Me[row, col].RichText, Me.Columns[col].width) + (Me.Rows.Height - Me.Font.Height))
    If $alternate Then Me[row, col].Background = IIf(Row Mod 2 = 0, Color.TextBackground, Color.Background)

End

Extraído del control wGrid que subí por algún lado hace ni se sabe.

Tengo que probar la solución de Grandamakulo, si funciona es mucho más simple y rápido que el mío.

Saludos.

No podemos regresar
Grandamakulo   17-03-2025, 19:35
#9
A mí me funciona, lo implemento en el evento _ColumnResize:

Código:
Public Sub grwPral_ColumnResize(Column As Integer)

  Dim i As Integer
 
  For i = 0 To grwPral.Rows.Max
    grwPral.Rows[i].Height = -1
  Next

End

En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
Shordi   18-03-2025, 13:36
#10
La solución de Grandamakulo sólo es válida para GridViews con pocas líneas, porque recorre el millón de filas y vuelve a tardar la vida.
He intentado pasar esa solución al evento Data... pero cambiar el tamaño de la fila dispara a su vez el evento Data y se produce un desbordamiento de pila.

La que me funciona es la que encontré en su día... eso sí, hay que trabajar con el Richtext de las celdas en lugar del  Text y colocarlo en el evento data. Para éste ejemplo sería:

Código:
Public Sub MostrarTablaEnGridView(nomtabla As String)

  Dim HRsf As ResultField
  Dim columna As Integer

  HResul = ModGestBase.MostrarTabla(nomtabla)
  With grdTabla
    .Columns.Count = HResul.Fields.Count
    .Header = .Both
    .Mode = Select.Single
  End With

  For Each HRsf In HResul.Fields
    grdTabla.Columns[columna].Text = HRsf.Name
    grdTabla.Columns[columna].Expand = True  'Por supuesto, si no el ancho es fijo '
    columna += 1
  Next

  grdTabla.Rows.Count = HResul.Count

End
Public Sub grdTabla_Data(Row As Integer, Column As Integer)
  HResul.MoveTo(Row)
  grdTabla.Data.WordWrap = True
  grdTabla.Data.RichText = HResul[grdTabla.Columns[Column].Text] 'Tenemos que trabajar con Richtext para calcular el alto.'
  grdTabla.Rows[row].Height = Max(grdTabla.Rows[row].Height, grdTabla.Data.Font.RichTextHeight(grdTabla.Data.richText, grdTabla.Columns[column].width) + (grdTabla.Rows.Height - grdTabla.Font.Height + 4))
End

El tema no es perfecto porque se me amplía bien, pero si se hace el gridview más grande y el ancho de las celdas aumenta, las filas no se encogen de alto... Es un fallo menor porque el texto sigue viéndose bien. Para encogerlas habría que cambiar el Mas(grdTabla... etc por un Min(grdTabla... etc) Sólo que me da pereza hacerlo ahora mismo.

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

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.