【问题标题】:Passing file path in Delphi from TOpenDialog as a string从 TOpenDialog 将 Delphi 中的文件路径作为字符串传递
【发布时间】:2014-06-27 08:23:30
【问题描述】:

我正在尝试使用 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;

【问题讨论】:

    标签: string delphi widestring topendialog


    【解决方案1】:

    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 将一无所获。

    最后,您将所有功能、选择文件名的代码和处理数据库连接的代码混合在一起。最好将关注点分开。创建一个简单地返回文件名的方法,该文件名是通过让用户通过对话框进行选择而获得的。并添加一个处理数据库连接的方法,即传递一个文件名作为参数。

    【讨论】:

    • 是的,这里的关键是您在将所选文件名添加到连接字符串时错过了 Filename 属性。
    【解决方案2】:

    您需要在释放对话框之前获取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 文件(.xls.xlsx),如 Excel Files|*.xls* .

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      • 2020-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多