#delphi #ado #delphi-xe #dbase
#delphi #ado #delphi-xe #база данных
Вопрос:
У меня есть эти элементы в моем файле dbase (.dbf)
INDICE NOME COR ESTILO ESCALA
100 SAOJOAO 18 0,00
Мне нужно изменить имя столбца INDICE
на ID
, поэтому я использую этот код:
while not ADOQuery1.Eof do
begin
Adoquery1.Edit;
ADOQuery1.FieldByName('NOME').TEXT:= 'ID';
Adoquery1.Post;
ADOQuery1.Next;
end;
Когда я запускаю выше, я получаю эти результаты:
INDICE NOME COR ESTILO ESCALA
ID SAOJOAO 18 0,00
Используемая строка подключения:
Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=C:_workspaceprojectsDBFEditortemp
У меня есть система, которая нуждается в импорте файла dbf и распознает только файл с именем столбца id.
Комментарии:
1. Сообщение об ошибке правильное:
DisplayName
свойство aTField
доступно только для чтения (см. Интерактивную справку по TField). Если вы пытаетесь установить дляDisplayLabel
поля значение ‘ID’, то сделайте это, но вы не должны делать это внутри цикла, сделайте это заранее. Если вы пытаетесь установить значение поля, используйте Field. asString, AsInteger и т.д.2. Я думаю, вам следует начать все сначала и переписать свой q, чтобы точно объяснить, что вы пытаетесь сделать. Тем временем я голосую за закрытие…
3. Я не думаю, что это можно было бы сделать с помощью ado. Какую строку подключения вы используете для открытия файла Excel? и зачем вам нужно программно изменять имя столбца Excel?
4. «Driver={Microsoft dBase Driver (*.dbf)} […]» Все это должно быть в вашем вопросе. И, опять же, какое отношение к этому имеет Excel?
5. Я думаю, что вы путаете «Excel» с «таблицей базы данных». Я вообще не вижу здесь никаких доказательств того, что вы используете Excel.
Ответ №1:
Демонстрационный проект ниже показывает способ сделать то, что вы, кажется, хотите. Я не утверждаю, что это самый эффективный способ или лучший способ, но это, вероятно, настолько просто, насколько вы, вероятно, получите.
Если вы хотели просто изменить отображаемое имя поля в приложении Delphi, например, в заголовке столбца DBGrid, вы могли бы сделать это, изменив DisplayLabel
свойство рассматриваемого поля ( AdoQuery1.FieldByName('INDICE').DisplayLabel := 'ID'
), как я сказал в комментарии ранее. Но в вашей последней правке кажется, что на самом деле вы хотите изменить имя столбца INDICE так, как оно отображается программой, считывающей файл данных в ID. Для этого вам необходимо внести изменения в структуру вашего файла dbf на диске .Файл DBF. Это то, что делает мой приведенный ниже код.
Он использует пользовательский DSN, настроенный для драйвера MS ODBC для файлов dBase, в качестве цели строки подключения ADOConnection.
В идеале, мне бы хотелось найти вариант Sql-инструкции ALTER TABLE, которая просто переименовала бы столбец INDICE, но драйвер MS dBase, похоже, не поддерживает это, потому что он сгенерировал исключение, когда я попытался. Поэтому вместо этого мой код работает путем создания копии таблицы и ее содержимого, а столбец INDICE переименован в ID.
Короче говоря, программа
-
Создает таблицу MATest с первым столбцом с именем INDICE и парой других столбцов и вставляет в него одну строку. Это просто для настройки таблицы для работы.
-
Создает вторую таблицу MATest2 с той же структурой, что и MATest, за исключением того, что первый столбец называется ID, а не INDICE.
-
Заполняет таблицу MATest2, копируя все строки из MATest, используя инструкцию INSERT INTO Sql.
Важные шаги для того, что вы хотите сделать, выполняются в btnCreateTableCopyClick
процедуре. Обратите внимание, что вам придется закомментировать первые две строки, которые удаляют таблицу MATest2 при первом запуске приложения, иначе оно будет загадочно жаловаться, что MATest2 нельзя удалить, потому что он не существует.
Я предоставляю вам адаптировать код по мере необходимости к вашим данным.
Код:
type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
btnCreateSrcTable: TButton;
ADOQuery1: TADOQuery;
btnOpenSrcTable: TButton;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
btnDropTable: TButton;
btnCreateTableCopy: TButton;
procedure btnCreateSrcTableClick(Sender: TObject);
procedure btnDropTableClick(Sender: TObject);
procedure btnOpenSrcTableClick(Sender: TObject);
procedure btnCreateTableCopyClick(Sender: TObject);
private
protected
public
procedure CreateSourceTable;
end;
[...]
procedure TForm1.btnCreateTableCopyClick(Sender: TObject);
var
Sql : String;
begin
Sql := 'drop table MATest2';
AdoConnection1.Execute(Sql);
Sql := 'create table MATest2(ID int, AName char(20), AValue char(20))';
AdoConnection1.Execute(Sql);
Sql := 'insert into MATest2 select INDICE, AName, AValue from MATest';
AdoConnection1.Execute(Sql);
end;
procedure TForm1.btnCreateSrcTableClick(Sender: TObject);
begin
CreateSourceTable;
end;
procedure TForm1.btnDropTableClick(Sender: TObject);
var
Sql : String;
begin
// Sql := 'drop table MATest';
// AdoConnection1.Execute(Sql);
end;
procedure TForm1.btnOpenSrcTableClick(Sender: TObject);
begin
AdoQuery1.Open;
end;
procedure TForm1.btnCreateTableCopyClick(Sender: TObject);
var
Sql : String;
begin
Sql := 'drop table MATest2';
AdoConnection1.Execute(Sql);
Sql := 'create table MATest2(ID int, AName char(20), AValue char(20))';
AdoConnection1.Execute(Sql);
Sql := 'insert into MATest2 select INDICE, AName, AValue from MATest';
AdoConnection1.Execute(Sql);
end;
procedure TForm1.CreateSourceTable;
var
Sql : String;
begin
Sql := 'create table MATest(INDICE int, AName char(20), AValue char(20))';
AdoConnection1.Execute(Sql);
Sql := 'insert into MATest(INDICE, AName, AValue) values(1, ''aaa'', ''vvv'')';
AdoConnection1.Execute(Sql);
end;
Очевидно, что было бы лучше сгенерировать ваши данные с идентификатором fieldname в первую очередь и избежать всего этого, но, по-видимому, есть веская причина, по которой вы не можете.
Комментарии:
1. Попробуйте это (не уверен, что это работает):
ALTER TABLE tablename RENAME COLUMN INDICE TO ID
2. @kobik: Спасибо, но я пробовал именно это, прежде чем опубликовать свой ответ, и он генерирует исключение, когда доступ к цели осуществляется через ADO и драйвер MS dBase.
3. Да, ADO не поддерживает оператор ALTER для изменения имен столбцов.