2010-10-07 3 views
1

J'ai une base de données remplissant un TDBGrid dans Delphi 2007 Pro. Lorsque la grille finit de remplir, je souhaite remplir automatiquement une zone de liste en fonction des données traitées à partir de la grille. Je peux le faire manuellement en regardant et en attendant que la grille se remplisse complètement avec l'ensemble de données, puis appelle ma prochaine procédure. Y at-il un événement qui permettrait d'appeler la procédure suivante lorsque la grille finit de remplir automatiquement? Merci.Comment puis-je savoir quand un TDBGrid Delphi a fini de remplir à partir d'une base de données?

+0

Quel est le descendant de TDataSet auquel TDBGrid est lié? Tout d'abord, rappelez-vous que DBGrid est juste une "fenêtre" pour afficher les données DataSet, donc peut-être que vous cherchez un événement sur le DataSet (regardez la réponse de @Sertac Akyuz). Par contre, vous avez également un composant TDBListBox que vous pouvez associer à votre DataSource et qui est automatiquement "rempli", comme le TDBGrid. – jachguate

Répondre

3

Si vous utilisez un descendant TDataSet, vous pouvez utiliser son événement AfterOpen:

"AfterOpen is called after the dataset establishes access to its data and the dataset is put into dsBrowse state."


modifier (exemple de code pour les commentaires de Duilio's answer): Dans le ci-dessous, la CDS est un 'TClientDataSet'. Un 'TDBGrid' est également attaché à l'ensemble de données au moyen d'un 'TDataSource', mais la fonctionnalité de la grille n'est pas affectée par le code ci-dessous, ou la fonctionnalité de la ListBox avec la grille d'ailleurs.

procedure TForm1.CDSAfterOpen(DataSet: TDataSet); 
var 
    sl: TStringList; 
begin 
    sl := TStringList.Create; 
    try 
    sl.Sorted := True; 
    sl.Duplicates := dupIgnore; 

    DataSet.DisableControls; 
    try 
     DataSet.First; 
     while not DataSet.Eof do begin 
     sl.Add(DataSet.Fields[1].AsString); 
     DataSet.Next; 
     end; 
     DataSet.First; 
    finally 
     DataSet.EnableControls; 
    end; 

    ListBox1.Items.Assign(sl); 
    finally 
    sl.Free; 
    end; 
end; 
+0

Correct, le DBGrid est une "fenêtre". Je pensais que je devrais travailler au niveau TDataSet. AfterOpen se déclenche quelques secondes avant que le TDBGrid soit rempli, ce qui génère une erreur. Un TDBListBox est une excellente idée. Ce que je fais lorsque le TDBGrid a fini de remplir toutes ses lignes à partir de la base de données, je trier un des champs dans une liste de chaînes: sl: = TStringList.Create; sl.Sorted: = Vrai; sl.Duplicates: = dupIgnore; et mettez cela dans une boîte de liste ordinaire. Je ne suis pas sûr comment je ferais cela avec un TDBListBox. Merci pour les suggestions, je vais essayer certaines choses. – SteveJG

+0

@Steve - 'AfterOpen' est * vraiment * déclenché lorsque l'ouverture du DatSet est terminée. Assurez-vous que c'est le DataSet lié à la source de données de la grille ... En ce qui concerne un 'TDBListBox', contrairement à un DBGrid, ce n'est pas un contrôle à remplir avec des données provenant de plusieurs enregistrements. Voir sa [documentation] (http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/FR/html/devwin32/12ctrlsusingtdblistboxandtdbcombobox_xml.html). –

+0

Sertac, merci. Cet exemple de code fait exactement ce dont j'ai besoin. Le DBListBox remplit correctement même avant que le DBGrid ait fini de remplir, Il semble toujours qu'il n'y ait aucun moyen de savoir (autre que par inspection), lorsque le DBGrid finit de remplir. Bon travail. – SteveJG

0

Je pense que vous pouvez exécuter:

TDataSet.Open; 
TDataSet.FetchAll; 
{At this point DBGrid should be populated} 

Cela obtenir toutes les données de votre table. Lorsque vous avez terminé, votre DBGrid devrait être rempli.

+0

Cela pourrait fonctionner pour remplir la grille. Au moment où l'ensemble de données a environ 6000 enregistrements, et nécessite environ une seconde d'ouverture pour remplir le DBGrid. Je n'ai aucun problème à remplir la grille; ce qui ne semble pas possible est de déterminer quand la grille est remplie et ensuite exécuter une autre fonction à la fin, c'est-à-dire exécuter la fonction dès que la grille "sait" qu'elle est remplie avec l'ensemble de données. Le DBGrid ne semble pas avoir un événement WhenFinishedPopulating à partir d'un ensemble de données. Merci pour votre idée, cela ne résout tout simplement pas le problème. – SteveJG

+0

@Steve - Si vous ne faites aucun 'ProcessMessages' lors de la récupération de vos données, vous pouvez essayer d'envoyer un message à votre formulaire, comme dans [cette réponse] (http://stackoverflow.com/questions/382527/delphi- app-initialisation-best-practices-approach/382860 # 382860). Vous pouvez également essayer de dériver un descendant 'TDBGrid' et remplacer son 'LayoutChanged' ensemble en utilisant un drapeau global peut-être. * Mais * pourquoi/comment votre code dépend-il de l'état de la grille ?, comment la grille * traite * les données?Si vous avez besoin d'enregistrements, ils sont dans l'ensemble de données ... –

+0

J'ai temporairement résolu le problème en utilisant une minuterie. Pas idéal, mais il charge la fonction que je veux chargée "automatiquement". La fonction que j'exécute dépend du remplissage complet de la grille. Elle ne peut pas fonctionner avec des données incomplètes. La grille ne traite aucune donnée, la fonction le fait. Si je "besoin d'enregistrements, ils sont dans l'ensemble de données" est vrai .. Je peux facilement copier toutes les données de terrain dont j'ai besoin dans un DBListBox .. Je reçois une liste complète, cependant, je ne veux pas une liste complète .. besoin d'une liste avec des doublons supprimés et "alphabétisés". – SteveJG

Questions connexes