将Delphi中的文件路径从TOpenDialog作为字符串传递

时间:2014-06-27 08:23:31

标签: string delphi widestring topendialog

我试图利用TOpenDialog将所选文件的路径传递给AdoConection,并将Excel文件的内容加载到表中。我目前正在尝试下面的代码,但代码的最后一部分没有连接到Excel返回错误: [dcc32错误] sample_map.pas(80):E2010不兼容的类型:' string'和' 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;

2 个答案:

答案 0 :(得分: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是pre-Unicode,那么你也可以安全地使用string,在这种情况下是AnsiString的别名。您使用的文字是ASCII。文件对话框是ANSI控件,因此openDialog.FileName也是ANSI。使用WideString无法获得任何结果。

最后,您正在混合,一体化功能,代码选择文件名,代码处理数据库连接。最好将问题分开。创建一个简单返回文件名的方法,通过让用户通过对话框选择获得文件名。并添加一个方法来处理数据库连接,即将文件名作为参数传递。

答案 1 :(得分: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;

作为附注,如果您不知道:如果您输入{{1},您可以使用单个过滤器选择所有Excel文件({1}}和.xls) },如.xlsx

而且,正如David所说,最好的方法是将获取文件名的代码和作为单独函数进行连接的代码分开。调用第一个获取文件名,然后将该文件名传递给第二个,以便在选择文件名时实际进行连接。