Изменить имя столбца файла dbf

#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:_workspaceprojectsDBFEditorte‌​mp

У меня есть система, которая нуждается в импорте файла dbf и распознает только файл с именем столбца id.

Комментарии:

1. Сообщение об ошибке правильное: DisplayName свойство a TField доступно только для чтения (см. Интерактивную справку по 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.

Короче говоря, программа

  1. Создает таблицу MATest с первым столбцом с именем INDICE и парой других столбцов и вставляет в него одну строку. Это просто для настройки таблицы для работы.

  2. Создает вторую таблицу MATest2 с той же структурой, что и MATest, за исключением того, что первый столбец называется ID, а не INDICE.

  3. Заполняет таблицу 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 для изменения имен столбцов.