我试图利用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;
答案 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所说,最好的方法是将获取文件名的代码和作为单独函数进行连接的代码分开。调用第一个获取文件名,然后将该文件名传递给第二个,以便在选择文件名时实际进行连接。