Передача пути к файлу в Delphi из TOpenDialog в виде строки
Я пытаюсь использовать TOpenDialog, чтобы передать путь к выбранному файлу в AdoConection и загрузить содержимое файла Excel в таблицу. В настоящее время я пытаюсь выполнить приведенный ниже код, но последняя часть кода не подключается к Excel, возвращая ошибку:[dcc32 Error] 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 ответа
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
,
Наконец, вы смешиваете все в одной функции, код для выбора имени файла и код для работы с подключением к базе данных. Лучше разделять проблемы. Создайте метод, который просто возвращает имя файла, полученное путем выбора пользователя в диалоговом окне. И добавьте метод для работы с подключением к базе данных, которому в качестве параметра передается имя файла.
Вам нужно получить 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;
Как примечание, если вы не знаете: вы можете выбрать все файлы Excel (оба .xls
а также .xlsx
) с одним фильтром, если вы вводите его как .xls*
, как в Excel Files|*.xls*
,
И, как говорит Дэвид, лучшим способом было бы разделить код, который получает имя файла, и код, который выполняет соединение, как отдельные функции. Вызовите первое, чтобы получить имя файла, а затем передайте это имя второму, чтобы фактически выполнить соединение, если имя файла выбрано.