Board index » delphi » int -> float run-time conversion

int -> float run-time conversion

Hi,

in Europe with the Euro entrance lot's of app's are changing and upgrading.
I need to build a patch .exe file to convert my clients Delphi5 / Paradox
app's integer fields to float fields.
The values in the database can not be deleted of course.

Wich is the best way to do that ?
Use SQL Alter Table statement ?
Use Delphi code ?

How can i do if the safe/fast way ?
Thanks,
Pedro MG
www.tquadrado.com

 

Re:int -> float run-time conversion


Local SQL cannot change the type of a column and preserve the data. If you
want to use SQL you will have to add a temporary column, copy the data to
it, drop the original column, add a new column with the old name and new
type, copy the data back then drop the temporary column.

The alternative is to use the BDE DbiDoRestructure API call. There are some
examples at www.borland.com/devsupport/bde/bdeapiex. The following is
another example of using DbiDoRestructure.

UNIT cTableRestruct;
{
Freeware by Brett W. Fleming 1999
SetOperation method added by Bill Todd 1999
SetFieldSubType method added by Michael Akin Jan 11, 2000

 Know field Types So Far (Jan 11, 2000)

 Type Name        Type          Sub Type
  Number           7              0
  Currency         7             21
  Integer          6              0
  Date             2              0
  Logical          4              0

 }

interface

uses
  BDE, DbTables;

type
  TTableRestructure = class(TObject)
  private
    function GetField(Index: Integer): PFLDDesc;
    function GetFieldLength(Index: Integer): Word;
    function GetFieldName(Index: Integer): String;
    function GetFieldType(Index: Integer): Word;
    function GetFieldSubType(Index: Integer): Word;
    function GetFieldUnits(Index: Integer): Word;
    function GetOperation(Index: Integer): PCROpType;
    procedure SetFieldLength(Index: Integer; const Value: Word);
    procedure SetFieldType(Index: Integer; const Value: Word);
    procedure SetFieldSubType(Index: Integer; const Value: Word);
    procedure SetFieldUnits(Index: Integer; const Value: Word);
    procedure SetFieldName(Index: Integer; const Value: String);
    procedure DetailError(ErrorCode: DbiResult);
    procedure SetOperation(Index: Integer; OpType: PCROpType);

  protected
    Fields: PFLDDesc;
    Operations: PCROpType;
    LocalFieldCount: Integer;

    procedure DestroyFieldDescriptors;

  public
    constructor Create;
    destructor Destroy; override;
    function AddField: Integer;
    function DeleteField(Index: Integer): Boolean;
    function FindField(Name: String): Integer;
    procedure LoadTableStructure(Table: TTable);
    procedure SaveTableStructure(Table: TTable);
    procedure PrintStructure;

    property FieldCount: Integer read LocalFieldCount;
    property FieldLength[Index: Integer]: Word read GetFieldLength write
      SetFieldLength;
    property FieldName[Index: Integer]: String read GetFieldName write
      SetFieldName;
    property FieldType[Index: Integer]: Word read GetFieldType write
SetFieldType;
    property FieldSubType[Index: Integer]: Word read GetFieldSubType write
SetFieldSubType;

    property FieldUnits[Index: Integer]: Word read GetFieldUnits write
      SetFieldUnits;
    property Field[Index: Integer]: PFLDDesc read GetField;
    property Operation[Index: Integer]: pCROpType read GetOperation write
      SetOperation;
  end;

implementation

uses

SysUtils, Dialogs;

{ TTableRestructure }

//
// Purpose: To add a new field to the table
//
// Parameters: None
//
// Effects: A new blank field descriptor is created and added to the
internal
// list of Field Descriptors which is reallocated to accomodate the new
field
//
// Returns: Index of the new field in the array, or -1 if the operation
failed
//
function TTableRestructure.AddField: Integer;
var
  NewField: PFLDDesc;
  NewOperation: pCROpType;
begin
  Result := -1;
  if (Fields <> nil) then
  begin
    ReallocMem(Fields, (LocalFieldCount + 1) * SizeOf(FLDDesc));
    ReallocMem(Operations, (LocalFieldCount + 1) * SizeOf(CROpType));

    //Move to the new field and empty it out
    NewField := Fields;
    Inc(NewField, LocalFieldCount);
    FillChar(NewField^, SizeOf(FLDDesc), 0);
    NewField^.iFldNum := LocalFieldCount + 1;

    //Move to the new operation and set it to add
    NewOperation := Operations;
    Inc(NewOperation, LocalFieldCount);
    NewOperation^ := crAdd;

    Inc(LocalFieldCount);

    //Return the new fields index
    Result := LocalFieldCount - 1;
  end;
end;

//
// Purpose: To create a new instance of this class and initialize it's data
//
// Parameters: None
//
// Effects: See purpose
//
constructor TTableRestructure.Create;
begin
  Fields := nil;
  Operations := nil;
  LocalFieldCount := 0;
end;

//
// Purpose: To delete a specific field from the tables description
//
// Parameters:
// Index - Index of the field that is to be removed
//
// Effects: The field is removed from the array of Field Descriptors and
// the memory that contains the list is reallocated
//
// Returns: True if the operation was successfull, False otherwise
//
function TTableRestructure.DeleteField(Index: Integer): Boolean;
var
  FieldBefore,
  FieldAfter: PFLDDesc;
  OperationBefore,
  OperationAfter: PCROpType;
begin
  Result := False;
  if (Fields <> nil) and (LocalFieldCount > 0) and (Index >= 0)
    and(Index < LocalFieldCount) then
  begin
    //Find the spot before and after the field to delete
    FieldBefore := Fields;
    FieldAfter := Fields;
    Inc(FieldBefore, Index);
    Inc(FieldAfter, Index + 1);

    //Find the spot before and after the operation to delete
    OperationBefore := Operations;
    OperationAfter := Operations;
    Inc(OperationBefore, Index);
    Inc(OperationAfter, Index + 1);

    //Now copy the data over the field to delete
    Move(FieldAfter^, FieldBefore^, (LocalFieldCount - Index) *
SizeOf(FLDDesc));
    Move(OperationAfter^, OperationBefore^, (LocalFieldCount - Index) *
    SizeOf(CROpType));

    //Now shrink the allocated memory
    Dec(LocalFieldCount);
    ReallocMem(Fields, LocalFieldCount * SizeOf(FLDDesc));
    ReallocMem(Operations, LocalFieldCount * SizeOf(CROpType));

    Result := True;
  end;
end;

//
// Purpose: To destroy an instance of this class and any memory that was
// allocated
//
// Parameters: None
//
// Effects: See purpose
//
destructor TTableRestructure.Destroy;
begin
  DestroyFieldDescriptors;
end;

//
// Purpose: To destroy an array of field descriptors
//
// Parameters: None
//
// Effects: The Field Descriptors are freed, and the pointer set to nil
//
procedure TTableRestructure.DestroyFieldDescriptors;
begin
  if Fields <> nil then
  begin
    FreeMem(Fields);
    Fields := nil;
    FreeMem(Operations);
    Operations := nil;
    LocalFieldCount := 0;
  end;
end;

//
// Purpose: To show the details of any Error returned by the BDE routines
//
// Parameters:
// ErrorCode - Code returned byt the BDE
//
// Effects: None
//
procedure TTableRestructure.DetailError(ErrorCode: DbiResult);
var
  ErrorInfo: DBIErrInfo;
  ErrorString: string;
  ErrorString2: String;
begin
  if (ErrorCode <> dbiERR_NONE) then
  begin
    Check(DbiGetErrorInfo(True,ErrorInfo));
    if (ErrorCode = ErrorInfo.iError) then
    begin
      ErrorString := 'Error Number: ' + IntToStr(ErrorInfo.iError) + #10 +
#13;
      ErrorString := ErrorString + 'Error Code: ' +
String(ErrorInfo.szErrcode) +
      #10 + #13;

      if (StrLen(ErrorInfo.szContext[1]) <> 0) then
      ErrorString := ErrorString + 'Context1: ' +
String(ErrorInfo.szContext[1]) +
      #10 + #13;

      if (StrLen(ErrorInfo.szContext[2]) <> 0) then
      ErrorString := ErrorString + 'Context2: ' +
String(ErrorInfo.szContext[2]) +
      #10 +#13;

      if (StrLen(ErrorInfo.szContext[3]) <> 0) then
      ErrorString := ErrorString + 'Context3: ' +
String(ErrorInfo.szContext[3]) +
      #10 +#13;

      if (StrLen(ErrorInfo.szContext[4]) <> 0) then
      ErrorString := ErrorString + 'Context4: ' +
String(ErrorInfo.szContext[4]) +
      #10 +#13;
    end else begin
      SetLength(ErrorString2, dbiMaxMsgLen + 1);
      Check(DbiGetErrorString(ErrorCode, PChar(ErrorString2)));
      SetLength(ErrorString2, StrLen(PChar(ErrorString2)));
      ErrorString := ErrorString + ErrorString2;
    end;
    ShowMessage(ErrorString);
  end;
end;

//
// Purpose: To find a particular field's index by it's name
//
// Parameters:
// Name - Name of the field to find in the current list of fields
//
// Effects: None
//
// Returns: Index of the field if found, or -1 if not found
//
function TTableRestructure.FindField(Name: String): Integer;
var
  Index: Integer;
begin
  Result := -1;
  Index := FieldCount - 1;
  while (Index >= 0) and (Result < 0) do
  begin
    if CompareText(FieldName[Index], Name) = 0 then Result := Index;
    Dec(Index);
  end;
end;

//
// Purpose: To return a pointer to a specified Field Descriptor
//
// Parameters:
// Index - Index of the field descriptor
//
// Effects: None
//
// Returns: Pointer to a Field Descriptor or nil if Index isn't valid
//
function TTableRestructure.GetField(Index: Integer): PFLDDesc;
begin
  Result := nil;
  if (Fields <> nil) and (Index >= 0) and (Index < LocalFieldCount) then
  begin
    Result := Fields;
    Inc(Result, Index);
  end;
end;

//
// Purpose: Get method for the FieldLength property
//
// Parameters:
// Index - Index of a field descriptor
//
// Effects: None
//
// Returns: Length of the specified field or 0 if not field not found
//
function TTableRestructure.GetFieldLength(Index: Integer): Word;
var
  Field: PFLDDesc;
begin
  Result := 0;
  Field := GetField(Index);
  if Field <> nil then
    Result := Field^.iLen;
end;

//
// Purpose: Get method for the FieldName property
//
// Parameters:
// Index - Index of a field descriptor
//
// Effects: None
//
// Returns: Name of the specified field or '' if not field not found
//
function TTableRestructure.GetFieldName(Index: Integer): String;
var
  Field: PFLDDesc;
begin
  Result := '';
  Field := GetField(Index);
  if Field <> nil then
    Result := String(Field^.szName);
end;

//
// Purpose: Get method for the FieldType property
//
// Parameters:
// Index - Index of a field descriptor
//
// Effects: None
//
// Returns: Type of the specified field or -1 if not field not found
//
function TTableRestructure.GetFieldType(Index: Integer): Word;
var
  Field: PFLDDesc;
begin
  Result := 0;
  Field := GetField(Index);
  if Field <> nil then
    Result :=
...

read more »

Re:int -> float run-time conversion


Thanks Bill,
i an analyzing the code you sent me.
However how can i rapidly change, for example:

TableInvoice.FieldByName('Total') from integer to currency ?

Thanks,
Pedro MG
www.tquadrado.com

Re:int -> float run-time conversion


Thanks Brian,

i'll take a look at his code later. Seems to have good stuffs.

Regards,
Pedro MG
www.tquadrado.com

"Brian Bushay TeamB" <BBus...@Nmpls.com> wrote in message
news:9oli1u0k4ecvhg3ma07uhcsggkqa48pqen@4ax.com...

Quote
> >Wich is the best way to do that ?
> >Use SQL Alter Table statement ?
> >Use Delphi code ?

> Alter Table with Paradox is not going to allow you to change an existing
field
> to a new datatype.  You would have to add a new field use a query to move
the
> data to that field then another DDL query to drop the old field.

> Delphi code using the BDE API function dbiDoRestructure will allow you to
change
> the field's datatype.
> You may want to look at http://www.rksolution.cz/  PXUPGR utility

> --
> Brian Bushay (TeamB)
> Bbus...@NMPLS.com

Re:int -> float run-time conversion


The only way is to use the DbiDoRestructure API function or find a third
party component that will do what you want.

--
Bill
(TeamB cannot answer questions received via email)

Re:int -> float run-time conversion


Pedro

You could try Reinhard Kalinke's BDE Toolkit, it works really well for me.

You can find her at reinhard.kali...@t-online.de

Regards,

George

Quote
"Pedro MG" <supo...@tquadrado.com> wrote in message news:3c17c977_1@dnews...
> Hi,

> in Europe with the Euro entrance lot's of app's are changing and
upgrading.
> I need to build a patch .exe file to convert my clients Delphi5 / Paradox
> app's integer fields to float fields.
> The values in the database can not be deleted of course.

> Wich is the best way to do that ?
> Use SQL Alter Table statement ?
> Use Delphi code ?

> How can i do if the safe/fast way ?
> Thanks,
> Pedro MG
> www.tquadrado.com

Re:int -> float run-time conversion


:-]
i was meaning using your code...

Regards,
Pedro MG
www.tquadrado.com

"Bill Todd (TeamB)" <f...@foo.com> wrote in message news:3c18da8c_1@dnews...

Quote
> The only way is to use the DbiDoRestructure API function or find a third
> party component that will do what you want.

> --
> Bill
> (TeamB cannot answer questions received via email)

Re:int -> float run-time conversion


I did not write that code. All I did was make a small change to it about
three years ago when I found it in a post on these newsgroups. That is also
the last time I used it. All I know about it is what is in the comments in
the code.

--
Bill
(TeamB cannot answer questions received via email)

Other Threads