2014-06-27 102 views
0

我試圖使用TOpenDialog將路徑傳遞給AdoConection,並將Excel文件的內容加載到表中。我目前正在嘗試下面的代碼,但代碼的最後一部分沒有連接到Excel,返回錯誤: [dcc32錯誤] sample_map.pas(80):E2010不兼容的類型:'string'和'TOpenDialog'在Delphi中將文件路徑從TOpenDialog傳遞爲字符串

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; 

回答

4

openDialog是文件對話框的一個實例。它不是一個字符串。你需要閱讀的文件對話框對象的屬性FileName像這樣:

openDialog.FileName 

其實你已經在使用,在您的通話ShowMessage之一。

請確保您在致電Free之前閱讀此屬性,此問題中的代碼存在錯誤。

事實上,您需要養成使用try/finally來保護資源的習慣。無論何時您創建一個類的實例,您都需要確保它即使在出現異常時也會被銷燬。在你的代碼,你需要把它寫這樣的:

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; 

我也不認爲你需要在這裏使用WideString。如果您使用的是Unicode Delphi,那麼您可以使用本地string類型,該類型是UnicodeString的別名。如果你的Delphi是預編碼的,那麼你也可以安全地使用string,這種情況下AnsiString的別名。您使用的文字是ASCII。文件對話框是ANSI控件,因此openDialog.FileName也是ANSI。使用WideString無法獲得。

最後,您正在混合使用,所有功能都在一個函數中,代碼用於選擇文件名以及用於數據庫連接的代碼。分開擔憂更好。創建一個簡單地返回一個文件名的方法,通過讓用戶選擇一個對話框來獲得。並添加一個方法來處理數據庫連接,即傳遞一個文件名作爲參數。

+0

是的,這裏的關鍵是在將所選文件名添加到連接字符串時,您錯過了Filename屬性。 –

3

你需要得到釋放的對話框之前OpenDialog.FileName

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; 

當然,你工作得太辛苦了。該Dialogs單元有一個更簡單的方法來做到這一點使用PromptForFilename功能,從而無需創建和釋放完全的對話框:

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; 

作爲一個方面說明,如果你不知道:你可以如果您將其輸入爲.xls*(如Excel Files|*.xls*),請使用單個過濾器選擇所有Excel文件(包括.xls.xlsx)。

而且,正如David所說,最好的辦法是將獲取文件名的代碼和作爲單獨函數進行連接的代碼分開。調用第一個獲取文件名,然後將該文件名傳遞給第二個,以便在選擇文件名時實際進行連接。

相關問題