2014-06-27 6 views
0

J'essaie d'utiliser TOpenDialog afin de passer le chemin du fichier sélectionné à AdoConection et de charger le contenu du fichier Excel dans la table. Je tente actuellement le code ci-dessous, mais la dernière partie du code ne se connecte pas à l'Excel renvoyant une erreur: [Erreur dcc32] sample_map.pas (80): E2010 Types incompatibles: 'string' et 'TOpenDialog'Passer le chemin du fichier dans Delphi à partir de TOpenDialog en tant que chaîne

procedure TForm1.Button1Click(Sender: TObject); 
var 
    openDialog : TOpenDialog; // Open dialog variable 
    strConn : WideString; // Declare wide string for the connection 

begin 
    // Create the open dialog object - assign to our open dialog variable 
    openDialog := TOpenDialog.Create(self); 

    // Set up the starting directory to be the current one 
    openDialog.InitialDir := GetCurrentDir; 

    // Only allow existing files to be selected 
    openDialog.Options := [ofFileMustExist]; 

    // Allow only .dpr and .pas files to be selected 
    openDialog.Filter := 
    'Excel 2003 and older|*.xls|Excel 2007 and older|*.xlsx'; 

    // Select pascal files as the starting filter type 
    openDialog.FilterIndex := 2; 

    // Display the open file dialog 
    if openDialog.Execute 
    then ShowMessage('File : '+openDialog.FileName) 
    else ShowMessage('Open file was cancelled'); 

    // Free up the dialog 
    openDialog.Free; 

    // Connect the Excel file 
    strConn:='Provider=Microsoft.Jet.OLEDB.4.0;' + 
       'Data Source=' + openDialog + ';' + 
       'Extended Properties=Excel 8.0;'; 
     AdoConnection1.Connected:=False; 
     AdoConnection1.ConnectionString:=strConn; 
end; 

Répondre

4

openDialog est une instance d'une boîte de dialogue de fichier. Ce n'est pas une chaîne. Vous devez lire la propriété FileName de l'objet de dialogue de fichier comme ceci:

openDialog.FileName 

En fait, vous utilisez déjà que dans un de vos appels ShowMessage. Assurez-vous de lire cette propriété avant d'appeler le Free, une erreur présente dans le code de la question.

En fait, vous devez prendre l'habitude d'utiliser try/finally pour protéger les ressources. Chaque fois que vous créez une instance d'une classe, vous devez vous assurer qu'elle sera détruite même en cas d'exception. Dans votre code, vous devez l'écrire comme ceci:

openDialog := TOpenDialog.Create(self); 
try 
    .... // use openDialog to let user choose file: 
    strConn := 'Provider=Microsoft.Jet.OLEDB.4.0;' + 
      'Data Source=' + openDialog.FileName + ';' + 
      'Extended Properties=Excel 8.0;'; 
finally 
    openDialog.Free; // executes no matter what, even if exception raised, etc. 
end; 

Je ne pense pas non, vous devez utiliser WideString ici. Si vous utilisez un Delphi Unicode, vous pouvez utiliser le type natif string qui est un alias pour UnicodeString. Si votre Delphi est pré-Unicode, vous pouvez également utiliser en toute sécurité string, un alias pour AnsiString dans ce cas. Les littéraux que vous utilisez sont ASCII. La boîte de dialogue de fichier est un contrôle ANSI et donc openDialog.FileName est également ANSI. Rien à gagner en utilisant WideString.

Enfin, vous mélangez, tout en une fonction, du code pour sélectionner un nom de fichier et du code pour travailler sur une connexion à une base de données. Il est préférable de séparer les préoccupations. Créez une méthode qui renvoie simplement un nom de fichier, obtenue en laissant l'utilisateur choisir via une boîte de dialogue. Et ajouter une méthode pour travailler sur la connexion à la base de données, qui est passé un nom de fichier en tant que paramètre.

+0

Oui, la clé ici est que vous avez manqué la propriété Filename lors de l'ajout du nom de fichier sélectionné dans la chaîne de connexion. –

3

Vous devez obtenir le OpenDialog.FileName avant de libérer la boîte de dialogue:

OpenDialog := TOpenDialog.Create(nil); 
try 
    // Set up the OpenDialog as before 

    // Display the open file dialog 
    if openDialog.Execute then 
    begin 
    strConn := 'Provider=Microsoft.Jet.OLEDB.4.0;' + 
       'Data Source=' + openDialog.FileName + ';' + 
       'Extended Properties=Excel 8.0;'; 
    // Connect the Excel file 
    AdoConnection1.Connected:=False; 
    AdoConnection1.ConnectionString:=strConn; 
    else 
    ShowMessage('Open file was cancelled'); 
finally 
    // Free up the dialog 
    openDialog.Free; 
end; 

Bien sûr, vous travaillez beaucoup trop dur. L'unité Dialogs a une façon de faire beaucoup plus facile grâce à la fonction PromptForFilename, ce qui élimine la nécessité de créer et de libérer la boîte de dialogue entièrement:

var 
    FileName: string; 
begin 

    FileName := ''; 
    if PromptForFileName(FileName,       // Chosen filename holder 
         'Excel 2003 and older|*.xls|Excel 2007 and older|*.xlsx'; // Filter(s) (optional) 
         '.xlsx',       // Default extension (opt) 
         'Choose file',      // Dialog title (opt) 
         GetCurrentDir,      // Initial dir (opt) 
         False) then      // Is it a save dlg? (opt) 
    begin 
    strConn := 'Provider=Microsoft.Jet.OLEDB.4.0;' + 
       'Data Source=' + FileName + ';' + 
       'Extended Properties=Excel 8.0;'; 
    // Connect the Excel file 
    AdoConnection1.Connected:=False; 
    AdoConnection1.ConnectionString:=strConn; 
    end 
    else 
    ShowMessage('Dialog cancelled.'); 
end; 

Comme une note de côté, au cas où vous ne connaissez pas: Vous pouvez sélectionnez tous les fichiers Excel (.xls et .xlsx) avec un seul filtre si vous l'entrez comme .xls*, comme dans Excel Files|*.xls*. Et, comme le dit David, le meilleur moyen serait de séparer le code qui obtient le nom de fichier et le code qui fait la connexion en tant que fonctions séparées. Appelez le premier pour obtenir le nom de fichier, puis passez ce nom de fichier à la seconde pour réellement faire la connexion si un nom de fichier est sélectionné.

Questions connexes