* * * *

Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

Trascinare un file nel programma
DB concetti fondamentali e ZeosLib
Recuperare codice HTML da pagina web
Mandare mail con Lazarus
Stabilire il sistema operativo
Esempio lista in pascal
File INI
Codice di attivazione
Realizzare programmi multilingua
Lavorare con le directory
Utilizzare Unità esterne
TTreeView
TTreeview e Menu
Generare controlli RUN-TIME
LazReport, PDF ed immagini
Intercettare tasti premuti
Ampliare Lazarus
Lazarus e la crittografia
System Tray con Lazarus
UIB: Unified Interbase
Il file: questo sconosciuto
Conferma di chiusura di un applicazione
Liste e puntatori
Overload di funzioni
Funzioni a parametri variabili
Proprietà
Conversione numerica
TImage su Form e Panel
Indy gestiore server FTP lato Client
PopUpMenu sotto Pulsante (TSpeedButton)
Direttiva $macro
Toolbar
Evidenziare voci TreeView
Visualizzare un file Html esterno
StatusBar - aggirare l'errore variabile duplicata
Da DataSource a Excel
Le permutazioni
Brute force
Indy 10 - Invio email con allegati
La gestione degli errori in Lazarus
Pascal Script
Linux + Zeos + Firebird
Dataset virtuale
Overload di operatori
Lavorare con file in formato JSON con Lazarus
Zeos ... dietro le quinte (prima parte)
Disporre le finestre in un blocco unico (come Delphi)
Aspetto retrò (Cmd Line)
Lazarus 1.0
Come interfacciare periferica twain
Ubuntu - aggiornare free pascal e lazarus
fpcup: installazioni parallele di lazarus e fpc
Free Pascal e Lazarus sul Raspberry Pi
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Creare un server multithread
guida all'installazione di fpc trunk da subversion in linux gentoo
Indice
DB concetti fondamentali e connessioni standard
Advanced Record Syntax
DB concetti fondamentali e DBGrid
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
Advanced Record Syntax: un esempio pratico
Superclasse form base per programmi gestionali (e non)
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Installare lazarus su mac osx sierra
immagine docker per lavorare con lazarus e free pascal
TDD o Test-Driven Development
Benvenuto! Effettua l'accesso oppure registrati.
Dicembre 26, 2024, 10:59:49 am

Inserisci il nome utente, la password e la durata della sessione.

96 Visitatori, 0 Utenti

Autore Topic: [RISOLTO] DBGrid, selezionare tutti i record visibili  (Letto 891 volte)

giacomarko

  • Full Member
  • ***
  • Post: 123
  • Karma: +6/-0
[RISOLTO] DBGrid, selezionare tutti i record visibili
« il: Dicembre 14, 2024, 12:27:54 pm »
Vorrei sapere se essite un metodo per selezionare tutti i record visibili in un oggetto DBGrid, che sia alternativo (e più veloce sopratutto) del solito ciclo:

Codice: [Seleziona]
        
  First;
  DisableControls;
  while not EOF do
   begin
       DBDataGrid.SelectedRows.CurrentRowSelected := True;
       Next;
   end;

in breve,

si parte da una DBGrid con molte colonne, per ogni colonna l'utente ha la possibilità di definire un filtro, e ad ogni filtro la DBGrid si riduce... alla fine quando l'utente ha "scremato" la lista dovrebbe selezionare tutto (questo per evitare di fare Ctrl+click per ogni record) e dopo lanciare una comando che esegua altro su ognuno di questi records.
Questo tipo di selezione è necessaria perchè successivamente utilizzo il Bookmark per eseguire altre operazioni sui record.

Il loop ovviamente funziona, ma è parecchio lento, per darvi un'idea, sul mio PC un I7 con 16Gb di Ram e W11 la selezione di 3354 records impiega 2 minuti e 11 sec

Certo potrei intervenire sulla query ma non voglio perchè i filtri sono molti e così come è strutturata la lista e la gestione funzionano perfettamente.

L'applicativo dovrà alla fine essere eseguito in rete, è vero che anche se da rete, non eseguendo accessi al disco ma solo sul controllo, teoricamente non dovrei avere un incremento di tempo... però anche così mi sembra troppo lungo

mi domando, un semplice comando "seleziona tutto" non esiste ? ... o almeno io non l'ho trovato

grazie

M
« Ultima modifica: Dicembre 23, 2024, 08:14:15 pm da giacomarko »
SO: W11
Release Lazarus: 3.0 del 2023.12.17 win32/win64
Versione FPC: 3.2.2
DB: MySQL 5.0, MSAccess

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1439
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:DBGrid, selezionare tutti i record visibili
« Risposta #1 il: Dicembre 14, 2024, 02:29:35 pm »
Vorrei sapere se essite un metodo per selezionare tutti i record visibili in un oggetto DBGrid, che sia alternativo (e più veloce sopratutto) del solito ciclo:
Il loop ovviamente funziona, ma è parecchio lento, per darvi un'idea, sul mio PC un I7 con 16Gb di Ram e W11 la selezione di 3354 records impiega 2 minuti e 11 sec
Io non saprei cosa dirti, non mi è mai servita una cosa simile.
Però, il tempo che hai indicato mi pare decisamente eccessivo, non vedo un reale motivo dietro a tale scadente prestazione.

Siamo, riflettendo su una linearità di prestazione, a circa 40 ms. a record selezionato, veramente un tempo abissale.

Forse vale la pena di indagare su ciò.

Ciao
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

giacomarko

  • Full Member
  • ***
  • Post: 123
  • Karma: +6/-0
Re:DBGrid, selezionare tutti i record visibili
« Risposta #2 il: Dicembre 14, 2024, 05:55:44 pm »
sui tempi (lungi e ingiustificati) sono assolutamente d'accordo con te, posto il codice completo, facile che abbia fatto qualche cag...a,

Codice: [Seleziona]
procedure TSDSList.SpeedButtonSelectAllClick(Sender: TObject);
var
  Duration : TDateTime;
begin
  Duration := Now();
  try
    Screen.Cursor := crHourglass;
    try
      DBDataGrid.SelectedRows.Clear;
      with DBDataGrid.Datasource.DataSet do
      begin
        First;
        DisableControls;
        while not EOF do
        begin
          DBDataGrid.SelectedRows.CurrentRowSelected := True;
          Next;
        end;
      end;
    except on E
      : ESQLDatabaseError do MessageDlg( DB_OPENING_ERROR + Self.Caption, mtError, [mbOK], 0);
    end;
  finally
    DBDataGrid.Datasource.DataSet.EnableControls;
    Screen.Cursor:= crDefault;
  end;
  ShowMessage( TASK_COMPLETED + ' in: ' + TimeToStr( Now() - Duration));
end;   

che dici ?
SO: W11
Release Lazarus: 3.0 del 2023.12.17 win32/win64
Versione FPC: 3.2.2
DB: MySQL 5.0, MSAccess

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1439
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:DBGrid, selezionare tutti i record visibili
« Risposta #3 il: Dicembre 14, 2024, 07:15:26 pm »
Il tuo codice sembrerebbe a posto.

Ho provato ad inserire in un DB SQLite con qualche colonna cinquemila righe di dati.

Il tuo metodo da me copiato paro paro funziona senza problemi e con tempi che variano tra 70 ms. a 72 ms. e non variano se usi o meno "DisableControls".

EDIT: ... in realtà variano (i tempi arrivano a 250 ms.). Avevo lasciato il disablecontrols attivo durante le prove ....

Ho usato connettore Zeos.
E' vero che ho un I9 serie 14 con 64GB di RAM, ma non ritengo cambi granchè con sistemi come il tuo.

Ne mi aspetto cambiamenti su DB diversi da SQLite, a meno che non siano DB remoti connessi tramite modem analogico a 1200 bit/s.

Stò usando Lazarus 3.6 FPC 3.2.2, Zeos 8.0.
« Ultima modifica: Dicembre 14, 2024, 07:22:16 pm da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

bonmario

  • Hero Member
  • *****
  • Post: 1380
  • Karma: +11/-1
Re:DBGrid, selezionare tutti i record visibili
« Risposta #4 il: Dicembre 14, 2024, 07:59:47 pm »

Il loop ovviamente funziona, ma è parecchio lento, per darvi un'idea, sul mio PC un I7 con 16Gb di Ram e W11 la selezione di 3354 records impiega 2 minuti e 11 sec


Hai già provato con i classici "DBGrid1.BeginUpdate" prima del ciclo, e "DBGrid1.EndUpdate" a fine ciclo?

Ciao, Mario

giacomarko

  • Full Member
  • ***
  • Post: 123
  • Karma: +6/-0
Re:DBGrid, selezionare tutti i record visibili
« Risposta #5 il: Dicembre 14, 2024, 08:45:47 pm »
Sono convinto anche io che il PC non possa fare tutta questa differenza,

ad ogni modo;

Inserito l'istruzione BeginUpdate ed EndUpdate, in effetti la prestazione migliora del 50% da 2:41 minuti scenda a 1:24 minuti  (vedi picture) grazie !

come componenti utilizzo quelli standard di Lazarus, :

TODBCConnection con TSQLTransaction, TSQLQuery e TDataSource per connessione e accesso ai dati
e come database, MSAccess, il tutto sullo stesso disco SSD dove lavora il programma
Lazarus è la versione 3.0

EDIT: Il fatto che la tabella abbia 52 colonne, non dovrebbe essere influente sulla "marcatura" del record, no?
« Ultima modifica: Dicembre 14, 2024, 08:50:19 pm da giacomarko »
SO: W11
Release Lazarus: 3.0 del 2023.12.17 win32/win64
Versione FPC: 3.2.2
DB: MySQL 5.0, MSAccess

tito_livio

  • Full Member
  • ***
  • Post: 186
  • Karma: +4/-0
Re:DBGrid, selezionare tutti i record visibili
« Risposta #6 il: Dicembre 14, 2024, 10:01:35 pm »
Ciao, potresti provare ad aumentare il valore della proprietà PacketRecords della query.
Di default è 10, magari se la imposti a 5000 si carica tutti i record in memoria ed è più veloce.
Può darsi però che all'inizio ci stia di più a caricare tutta la dbgrid in memoria, allora bisognerà trovare un valore più basso.
 
« Ultima modifica: Dicembre 14, 2024, 10:04:10 pm da tito_livio »

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1439
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:DBGrid, selezionare tutti i record visibili
« Risposta #7 il: Dicembre 15, 2024, 12:48:40 am »
come componenti utilizzo quelli standard di Lazarus, :

TODBCConnection con TSQLTransaction, TSQLQuery e TDataSource per connessione e accesso ai dati
e come database, MSAccess, il tutto sullo stesso disco SSD dove lavora il programma
Lazarus è la versione 3.0

EDIT: Il fatto che la tabella abbia 52 colonne, non dovrebbe essere influente sulla "marcatura" del record, no?
Diciamo che, come ti accennava @tito_livio, potrebbero esserci altre ottimizzazioni da fare ....

Intanto Access e ODBC non sono sicuramente i mezzi migliori e più performanti con cui lavorare. Però questo è un mio commento, nulla toglie al fatto che così è.

E' necessario verificare che il tuo dataset non venga effettivamente "ricaricato" o riallineato ogni qualvolta che ci accedi. Dai tempi che vengono mostrati, sembra che la tabella Access venga elaborata pesantemente gni volta che esegui un NEXT ... sarebbe necessario un consiglio da chi usa tale DB o ODBC per capire quali sono i settaggi migliori.

I componenti DB standard di Lazarus non sò come operino, quindi non sò dirti se ci siano dei settaggi che possano influire sulle prestazioni. Ho sempre usato ZEOS (e comunque mai in produzione) e non ho riscontrato differenze abissali con i componenti ad esempio di Delphi.

Secondo me le 52 colonne della tabella dovrebbero avere una influenza marginale sulle tempistiche. L'importante che il DB Access sia comunque indicizzato con chiave primaria e che l'accesso alla tabella sia secondo questa chiave (o una delle chiavi secondarie) per velocizzare i tempi.
« Ultima modifica: Dicembre 15, 2024, 12:50:19 am da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

bonmario

  • Hero Member
  • *****
  • Post: 1380
  • Karma: +11/-1
Re:DBGrid, selezionare tutti i record visibili
« Risposta #8 il: Dicembre 15, 2024, 07:57:21 am »
Sono convinto anche io che il PC non possa fare tutta questa differenza,

ad ogni modo;

Inserito l'istruzione BeginUpdate ed EndUpdate, in effetti la prestazione migliora del 50% da 2:41 minuti scenda a 1:24 minuti  (vedi picture) grazie !

come componenti utilizzo quelli standard di Lazarus, :

TODBCConnection con TSQLTransaction, TSQLQuery e TDataSource per connessione e accesso ai dati
e come database, MSAccess, il tutto sullo stesso disco SSD dove lavora il programma
Lazarus è la versione 3.0

EDIT: Il fatto che la tabella abbia 52 colonne, non dovrebbe essere influente sulla "marcatura" del record, no?

Ciao,
rileggendo c'è una cosa che non capisco di quello che hai scritto: quando inizi a misurare il tempo.
Io credo di aver capito che fai partire il timer DOPO aver popolato la tabella, e prima di iniziare il ciclo che serve a selezionare le righe.
Se è così, ignora quello che sto per scrivere, se invece inizi prima di popolare la DBGrid, non so se la situazione è la stessa, ma qualche mese fa ho avuto problemi di lentezza estrema nello scaricare alcune tabelle in formato CSV.
Alla fine ero arrivato a questo link: https://wiki.freepascal.org/Working_With_TSQLQuery ed avevo risolto seguendo il consiglio in fondo, di mettere

Codice: [Seleziona]
MySQLQuery.UniDirectional:=True;


Ciao, Mario

giacomarko

  • Full Member
  • ***
  • Post: 123
  • Karma: +6/-0
Re:DBGrid, selezionare tutti i record visibili
« Risposta #9 il: Dicembre 15, 2024, 09:37:51 am »
La tabella è già popolata di dati, di fatto, per i test e gli enhancement uso una copia del DB di produzione, scaricato in locale sul mio laptop,

tutte le tabelle hanno un indice primario numerico univoco,

adesso verifico il discorso dei packet record, anche se credo di aver già tolto il limite

vi aggiorno

EDIT: la proprietà PackedRecords è a -1 (quindi tutti i records presenti), e ad ogni modo, provato per curiosità a 1 o 10 o -1 stesso risultato

EDIT 2: anche il BeginUpdate ed EndUpdate non sono significativi, ieri ho riscontrato un 50% di miglioramento, ma questa mattina sono tornato agli stessi tempi, pur avendo ancora le stesse istruzioni, come dire che la prima volta è lunga ma la seconda migliora
« Ultima modifica: Dicembre 15, 2024, 10:33:12 am da giacomarko »
SO: W11
Release Lazarus: 3.0 del 2023.12.17 win32/win64
Versione FPC: 3.2.2
DB: MySQL 5.0, MSAccess

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1439
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:DBGrid, selezionare tutti i record visibili
« Risposta #10 il: Dicembre 15, 2024, 10:47:08 am »
EDIT 2: anche il BeginUpdate ed EndUpdate non sono significativi, ieri ho riscontrato un 50% di miglioramento, ma questa mattina sono tornato agli stessi tempi, pur avendo ancora le stesse istruzioni, come dire che la prima volta è lunga ma la seconda migliora
Il fatto che la prima attività sia così lenta (e continui ad essere così lenta senza BeginUpdate / EndUpdate) e la seconda migliori (comunque rimane un tempo non congruo) mi continua a fare pensare che le operazioni effettuate vadano a riflettersi direttamente sul DB.

Il fatto che dimezzi è sintomatico che viene posto in cache qualcosa (probabilmente l'intero DB) e quindi le successive elaborazioni sono un pò più veloci.

Mi dispiace non conoscere meglio l'interazione tra ODBC e Access. Con Access non ci ho mai lavorato, ai tempi (oltre vent'anni fà) usai per la maggiore MSDE200 con il suo SQLServer lite per poi passare a SQL Server Express.
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1439
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:DBGrid, selezionare tutti i record visibili
« Risposta #11 il: Dicembre 15, 2024, 11:10:07 am »
Per misurare i tempi con precisione al millisecondo (ma anche meno se vuoi, fino ai 0,1 microsecondi), puoi usare questa unità dove vuoi.
L'istanza è un advanced record, quindi non devi neanche preoccuparti di fare il free o usare il create.

L'unità è quella orginale FREE (supporta Windows e Linux) con qualche mio adattamento, ed è compatibile con quella usata anche in Delphi (migliorata da Embarcadero per lavorare in tutti i suoi target come Mac, Android, Ios etc...).

E' comoda e puoi istanziare quanti timer indipendenti vuoi (io ne uso a decine).
Puoi eseguire lo StartNew sulla stessa variabile quante volte vuoi (è di fatto la sequenza di Reset e Start).

Si usa così:

Codice: [Seleziona]
var Tim1: TStopWatch;
begin
  Tim1 := TStopWatch.StartNew;
  .....
  .....
  .....
  Tim1.Stop;
  //La lettura PUO' ESSERE EFFETTUATA SOLO CON LO STOP.
  //Poi puoi ad esempio:
  //Tim1.Reset      ---> Azzera il conteggio
  //Tim1.Start       ---> riparte il conteggio (si può usare anche prima di un Reset per continuare quello stoppato).
  ShowMessage(Tim1.ElapsedMilliseconds.ToString+' - '+i.ToString);
end;
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

giacomarko

  • Full Member
  • ***
  • Post: 123
  • Karma: +6/-0
Re:DBGrid, selezionare tutti i record visibili
« Risposta #12 il: Dicembre 15, 2024, 11:27:35 am »
GRAZIE !

per curiosità metterò in piedi un piccolo programma che accede alla stessa tabella utilizzando ZEOS,

vediamo se è il controllo o il DB
SO: W11
Release Lazarus: 3.0 del 2023.12.17 win32/win64
Versione FPC: 3.2.2
DB: MySQL 5.0, MSAccess

giacomarko

  • Full Member
  • ***
  • Post: 123
  • Karma: +6/-0
Re:DBGrid, selezionare tutti i record visibili
« Risposta #13 il: Dicembre 15, 2024, 01:55:33 pm »
Aggiornamento:

con un discreto dispiacere devo ammettere che la differenza più che il tipo di DB (MSAccess nel mio caso) la fà il componente,

quindi:
programmino exnovo, giusto un form con due DBGrid connesse allo stesso DB della applicazione di cui si parlava nei post precedenti,
la prima DBGrid connessa via ODBCConnection e la seconda via TZConnection, eseguo il loop per selezionare tutti i record,

risultati:
- sulla prima sempre 2 minuti e 40,
esco completamente, ricompilo e rientro,
- eseguo la seconda 0:0 secondi

Drago, non ho usato la tua unit, ma lo stesso sistema dell'esempio di codice postato, ma credo che il risultato sia già di per se chiaro  :-\

quello che mi "gira" nel passare tutto l'applicativo da SQLQuery a ZQuery, è che il componente nativo ha come proprietà le SQL di Update, Delete e Create oltre che la solita si Select, in pratica mi è sufficiente scrivere le query e assegnarle a SQLQuery.Update, SQLQuery.Create,  SQLQuery.Delete e nel codice le eseguo semplicemente con Insert e Post....  :)

vedrò .. ???

EDIT: ovviamente il codice per selezionare tutti i record, è lo stesso per entrambi ed è quello postato in precedenza
SO: W11
Release Lazarus: 3.0 del 2023.12.17 win32/win64
Versione FPC: 3.2.2
DB: MySQL 5.0, MSAccess

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1439
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:DBGrid, selezionare tutti i record visibili
« Risposta #14 il: Dicembre 15, 2024, 05:49:16 pm »
Guarda che penso che ZEOS sia perfettamente "identico" ai componenti standard in termini di sintassi, le funzioni principali sono quelle in SQL.

Quindi teoricamente non dovresti cambiare codice se inserisci i componenti nuovi e li nomini come i vecchi (magari qualche "virgola" ...., forse sugli eventi ....).

E' più facile da farsi che a dirsi.

Comunque mi fà piacere che tu abbia trovato l'inghippo. Quei tempi erano veramente da "urlo" ... di Munch però ...  ;D

Ciao
« Ultima modifica: Dicembre 15, 2024, 05:51:38 pm da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

 

Recenti

How To

Utenti
  • Utenti in totale: 802
  • Latest: maXim.FI
Stats
  • Post in totale: 19336
  • Topic in totale: 2304
  • Online Today: 111
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 0
Guests: 96
Total: 96

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.