//
Unit ads_Db; {Copyright(c)2016 Advanced Delphi Systems Richard Maley Advanced Delphi Systems 12613 Maidens Bower Drive Potomac, MD 20854 USA phone 301-840-1554 dickmaley@advdelphisys.com The code herein can be used or modified by anyone. Please retain references to Richard Maley at Advanced Delphi Systems. If you make improvements to the code please send your improvements to dickmaley@advdelphisys.com so that the entire Delphi community can benefit. All comments are welcome. } (*UnitIndex Master Index Implementation Section Download Units
Description: ads_Db.pas This unit contains the following routines.
AddTables CreateTableFromQuery DBAddQueryToTable DBAddTables DBCopyFieldAToB DBCopyTable DBCopyTableAToB DBCopyTableToServer DBCreateTableBorrowStr DBCreateTableFromQuery DBCreateTableFromTTable DBDeleteTable DBDropTable DBEmptyTable DBFieldNameByNo DBFieldNamesCommonToString DBFieldNamesCommonToTStrings DBFieldNamesToTStrings DBFieldNo DBFieldSize DBFieldType DBFieldTypeByNo DBGlobalStringFieldChange DBGlobalStringFieldChangeWhere DBGlobalStringFieldChangeWhere2 DBInsertMatchingFields DBKeyFieldNamesToTStrings DBLookUpDialog DBMedianSingle DBMoveTable DBNextAlphaKey DBNextInteger DBNFields DBParadoxCreateNKeys DBRecordMove DBReNameTable DBSchemaSame DBSessionCreateNew DBSqlValueQuoted DBSubtractTable DBTrimBlanksLeft DBTrimBlanksRight DBUpdateMatchingFields DeleteTable DialogDBLookUp DialogLookup DialogLookupDetail DropTable EmptyTable ErrorMeaning FieldNo FieldSize FieldType FieldTypeFromDataSet IsEmptyDataSource IsEmptyTable IsEmptyTQuery IsEmptyTTable IsField IsFieldKeyed IsRecord IsSchemaSame IsStructureSame IsTable IsTableKeyed LookupDialog MoveTable NFields SubtractTable TableAdd TableCreateFromQuery TableMove TableSubtract TEditKeyFilter.OnlyAToZ TEditKeyFilter.OnlyNumbers TEditKeyFilter.OnlyNumbersAbsolute TPanel_Cmp_Sec_ads.ResizeShadowLabel TypeField TypeFieldFromDataSet
*) Interface Uses DBTables, Classes, ExtCtrls, DB; Function DBCreateTableFromTTable( Table: TTable; NewTableName, TableDatabaseName: String): Boolean; {!~ Add source table to destination table} Function AddTables( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; {!~ Creates a new table from a Query. Complex joins can be output to a new table.} Function CreateTableFromQuery( Query: TQuery; NewTableName, TableDatabaseName: String): Boolean; {!~ Add source query to destination table} Procedure DBAddQueryToTable( DataSet : TQuery; const DestDatabaseName, DestinationTable: string); {!~ Add source table to destination table} Function DBAddTables( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; {!~ Copies Field A To Field B.} function DBCopyFieldAToB( DatabaseName, TableName, SourceField, DestField: String): Boolean; {!~ Copies SourceTable To DestTable. If DestTable exists it is deleted} Function DBCopyTable( SourceDatabaseName, SourceTable, DestDatabaseName, DestTable: String): Boolean; {!~ Copies Table A To Table B. If Table B exists it is emptied} Function DBCopyTableAToB( SourceDatabaseName, SourceTable, DestDatabaseName, DestTable: String): Boolean; {!~ Copies a table from the source to the destination. If the destination table exists the function will not throw an error, the existing table will be replaced with the new table.} Function DBCopyTableToServer( SourceDatabaseName : String; SourceTableName : String; DestDatabaseName : String; DestTableName : String): Boolean; {!~ Creates an empty table with indices by borrowing the structure of a source table. Source and destination can be remote or local tables. If the destination table exists the function will not throw an error, the existing table will be replaced with the new table.} Function DBCreateTableBorrowStr( SourceDatabaseName : String; SourceTableName : String; DestDatabaseName : String; DestTableName : String): Boolean; {!~ Creates a new table from a Query. Complex joins can be output to a new table.} Function DBCreateTableFromQuery( Query: TQuery; NewTableName, TableDatabaseName: String): Boolean; {!~ Deletes A Table} Function DBDeleteTable(const DatabaseName, TableName : string):Boolean; {!~ Drops A Table} Function DBDropTable(const DatabaseName, TableName : string):Boolean; {!~ Empties a table of all records} Function DBEmptyTable( const DatabaseName, TableName : string): Boolean; {!~ Returns the field Name as a String. If there is an error, the table doesn't exist, the field doesn't exist or some other reason '' is returned.} Function DBFieldNameByNo( DatabaseName : String; TableName : String; FieldNo : Integer): String; {!~ Returns Field Names shared by 2 tables as a string. Fields are separated by commas with no trailing comma.} Function DBFieldNamesCommonToString( DatabaseName1 : String; TableName1 : String; DatabaseName2 : String; TableName2 : String): String; {!~ Copies Field Names shared by 2 tables to a TStrings object. Returns true if successful. If there is an error, the DatabaseName doesn't exist, the table doesn't exist or some other reason False is returned. } Function DBFieldNamesCommonToTStrings( DatabaseName1 : String; TableName1 : String; DatabaseName2 : String; TableName2 : String; Strings : TStrings): Boolean; {!~ Copies Table Field Names to a TStrings object, e.g., ListBox1.Items, Memo1.Lines. Returns the true if successful. If there is an error, the DatabaseName doesn't exist, the table doesn't exist or some other reason False is returned. } Function DBFieldNamesToTStrings( DatabaseName : String; TableName : String; Strings : TStrings): Boolean; {!~ Returns the field Number as an integer. If there is an error, the table doesn't exist, the field doesn't exist or some other reason -1 is returned.} Function DBFieldNo(DatabaseName, TableName, FieldName: String): Integer; {!~ Returns the database field Size as an integer. If there is an error, the table doesn't exist, the field doesn't exist or some other reason 0 is returned.} Function DBFieldSize(DatabaseName, TableName, FieldName: String): Integer; {!~ Returns the database field type as a string. If there is an error, the table doesn't exist, the field doesn't exist or some other reason a null string is returned.} Function DBFieldType(DatabaseName, TableName, FieldName: String): String; {!~ Returns the database field type as a string. If there is an error, the table doesn't exist, the field doesn't exist or some other reason a null string is returned.} Function DBFieldTypeByNo(DatabaseName, TableName: String; FieldNo: Integer): String; {!~ Replace all the values in a field that match a condition value with a new value} procedure DBGlobalStringFieldChange( const DatabaseName, TableName, FieldName, NewValue : string); {!~ Replace all the values in a field with a new value} procedure DBGlobalStringFieldChangeWhere( const DatabaseName, TableName, FieldName, CurrentValue, NewValue : string); {!~ Replace values in a field (NewValueField) with NewValue based on a where condition in CurrentValueField with a value of CurrentValue} procedure DBGlobalStringFieldChangeWhere2( const DatabaseName, TableName, NewValueField, NewValue, CurrentValueField, CurrentValue: string); {!~ Inserts matching fields in a destination table. Source Table records are deleted if the record was inserted properly. Records unsuccessfully inserted are retained and the problems recorded in the ErrorField.} Function DBInsertMatchingFields( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable, ErrorField: string): Boolean; {!~ Copies Table Key Field Names to a TStrings object. Returns the true if successful. If there is an error, the DatabaseName doesn't exist, the table doesn't exist or some other reason False is returned. } Function DBKeyFieldNamesToTStrings( DatabaseName : String; TableName : String; Strings : TStrings): Boolean; {!~ Presents a lookup Dialog to the user. The selected value is returned if the user presses OK and the Default value is returned if the user presses Cancel unless the TStringList is nil in which case a blank string is returned} Function DBLookUpDialog( Const DataBaseName : String; Const TableName : String; Const FieldName : String; Const SessionName : String; Const DefaultValue : String; const DialogCaption : string; const InputPrompt : string; const DialogWidth : Integer ): String; {!~ Returns the median value for a column in a table as type single} Function DBMedianSingle( const DatabaseName, TableName, FieldName, WhereString : string): Single; {!~ Moves SourceTable From SourceDatabaseName To DestDatabasename. If a table exists with the same name at DestDatabaseName it is overwritten.} Function DBMoveTable( SourceTable, SourceDatabaseName, DestDatabaseName: String): Boolean; {!~ Returns the number of fields in a table} Function DBNFields(DatabaseName, TableName: String): Integer; {!~ Returns the next key value when the table keys are numbers as strings, e.g., ' 12' key would return ' 13'} Function DBNextAlphaKey(DatabaseName, TableName, FieldName: String):String; {!~ Returns the next key value when the table keys are integers, e.g., 12 key would return 13} Function DBNextInteger( DatabaseName, TableName, FieldName: String):LongInt; {!~ ReKeys a Paradox Table to the first N fields} Function DBParadoxCreateNKeys( DatabaseName : String; TableName : String; NKeys : Integer): Boolean; {!~ ReNames a table} Function DBReNameTable( DatabaseName, TableNameOld, TableNameNew: String): Boolean; {!~ Applies BatchMode Types As Appropriate To Source and Destination Tables} Function DBRecordMove( SourceDatabaseName, SourceTable, DestDatabaseName, DestTable: String; BMode: TBatchMode): Boolean; {!~ Returns True If The Tables Have Identical Structures, False Otherwise. If 1 Local Table is involved then Indices are ignored!!!!!!} Function DBSchemaSame(const DatabaseName1, Table1, DatabaseName2, Table2: string): Boolean; {!~ Creates a new TSession object.} {$IFDEF WIN32} Function DBSessionCreateNew: TSession; {$ENDIF WIN32} {!~ Returns a value for use in a sql where clause with the appropriate Quoting of the value based on its datatype. If an error occurs the original string value is returned unchanged} Function DBSqlValueQuoted( const DatabaseName, TableName, FieldName, FieldValue: string): String; {!~ Subtracts the records in the source table from the destination table} Function DBSubtractTable( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; {!~ Trims blank spaces from the Left of the string} Function DBTrimBlanksLeft( DatabaseName : String; TableName : String; FieldName : String): Boolean; {!~ Trims blank spaces from the right of the string} Function DBTrimBlanksRight( DatabaseName : String; TableName : String; FieldName : String): Boolean; {!~ Updates matching fields in a destination table. Source Table records are deleted if the record was updated properly. Records unsuccessfully updated are retained and the problems recorded in the ErrorField.} Function DBUpdateMatchingFields( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable, ErrorField: string; MsgPanel: TPanel; FilePath: String): Boolean; {!~ Deletes A Table} Function DeleteTable(const DatabaseName, TableName : string):Boolean; {!~ Presents a lookup Dialog to the user. The selected value is returned if the user presses OK and the Default value is returned if the user presses Cancel unless the TStringList is nil in which case a blank string is returned} Function DialogDBLookUp( Const DataBaseName : String; Const TableName : String; Const FieldName : String; Const SessionName : String; Const DefaultValue : String; const DialogCaption : string; const InputPrompt : string; const DialogWidth : Integer ): String; {!~ Presents a lookup Dialog to the user. The selected value is returned if the user presses OK and the Default value is returned if the user presses Cancel unless the TStringList is nil in which case a blank string is returned} Function DialogLookup( const DialogCaption : string; const InputPrompt : string; const DefaultValue : string; const Values : TStringList ): string; {!~ Presents a lookup Dialog to the user. The selected value is returned if the user presses OK and the Default value is returned if the user presses Cancel unless the TStringList is nil in which case a blank string is returned} Function DialogLookupDetail( Const DialogCaption : string; Const InputPrompt : string; Const DefaultValue : string; Const Values : TStringList; Const ButtonSpacing : Integer; Const SpacerHeight : Integer; Const TopBevelWidth : Integer; Const PromptHeight : Integer; Const FormHeight : Integer; Const FormWidth : Integer; Const Hint_OK : string; Const Hint_Cancel : string; Const Hint_ListBox : string; Const ListSorted : Boolean; Const AllowDuplicates : Boolean ): string; {!~ Drops A Table} Function DropTable(const DatabaseName, TableName : string):Boolean; {!~ Empties a table of all records} Function EmptyTable( const DatabaseName, TableName : string): Boolean; {!~ Returns the meaning of the given result code. Error codes are for Delphi 1.0.} function ErrorMeaning (ResultCode: Integer): string; {!~ Returns the field Number as an integer. If there is an error, the table doesn't exist, the field doesn't exist or some other reason 0 is returned.} Function FieldNo(DatabaseName, TableName, FieldName: String): Integer; {!~ Returns the database field Size as an integer. If there is an error, the table doesn't exist, the field doesn't exist or some other reason 0 is returned.} Function FieldSize(DatabaseName, TableName, FieldName: String): Integer; {!~ Returns the database field type as a string. If there is an error, the table doesn't exist, the field doesn't exist or some other reason a null string is returned.} Function FieldType(DatabaseName, TableName, FieldName: String): String; {!~ Returns the database field type as a string. If there is an error a null string is returned.} Function FieldTypeFromDataSet(DataSet: TDataSet; FieldName: String): String; {!~ Tests whether a TDataSource is empty, i.e., has no records } Function IsEmptyDataSource(DS: TDataSource): Boolean; {!~ Tests whether a TQuery is empty, i.e., has no records } Function IsEmptyTQuery(Query: TQuery): Boolean; {!~ Tests whether a TTable is empty, i.e., has no records } Function IsEmptyTTable(Table: TTable): Boolean; {!~ Tests whether a table is empty, i.e., has no records } Function IsEmptyTable(DatabaseName, TableName: String): Boolean; {!~ Returns True If DatabaseName:TableName:FieldName Exists, False Otherwise} Function IsField(DatabaseName, TableName, FieldName: String): Boolean; {!~ Returns True If DatabaseName:TableName:FieldName Exists and is Keyed, False Otherwise} Function IsFieldKeyed(DatabaseName, TableName, FieldName: String): Boolean; {!~ Returns True If The Record Exists, False Otherwise} Function IsRecord( DatabaseName : String; TableName : String; TableKeys : TStringList; KeyValues : TStringList): Boolean; {!~ Returns True If The Tables Have Identical Structures, False Otherwise. If 1 Local Table is involved then Indices are ignored!!!!!!} Function IsSchemaSame(const DatabaseName1, Table1, DatabaseName2, Table2: string): Boolean; {!~ Returns True If The Tables Have Identical Structures, False Otherwise. If 1 Local Table is involved then Indices are ignored!!!!!!} Function IsStructureSame(const DatabaseName1, Table1, DatabaseName2, Table2: string): Boolean; {!~ Returns True If The Table Exists, False Otherwise. This procedure needs to be improved. Please give recommendations or new code.} Function IsTable(DatabaseName, TableName: String): Boolean; {!~ Returns True If DatabaseName:TableName Exists and has a primary key, False Otherwise} Function IsTableKeyed(DatabaseName, TableName: String): Boolean; {!~ Presents a lookup Dialog to the user. The selected value is returned if the user presses OK and the Default value is returned if the user presses Cancel unless the TStringList is nil in which case a blank string is returned} Function LookupDialog( const DialogCaption : string; const InputPrompt : string; const DefaultValue : string; const Values : TStringList ): string; {!~ Moves SourceTable From SourceDatabaseName To DestDatabasename. If a table exists with the same name at DestDatabaseName it is overwritten.} Function MoveTable( SourceTable, SourceDatabaseName, DestDatabaseName: String): Boolean; {!~ Returns the number of fields in a table} Function NFields(DatabaseName, TableName: String): Integer; {!~ Subtracts the records in the source table from the destination table} Function SubtractTable( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; {!~ Add source table to destination table} Function TableAdd( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; {!~ Creates a new table from a Query. Complex joins can be output to a new table.} Function TableCreateFromQuery( Query: TQuery; NewTableName, TableDatabaseName: String): Boolean; {!~ Moves SourceTable From SourceDatabaseName To DestDatabasename. If a table exists with the same name at DestDatabaseName it is overwritten.} Function TableMove( SourceTable, SourceDatabaseName, DestDatabaseName: String): Boolean; {!~ Subtracts the records in the source table from the destination table} Function TableSubtract( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; {!~ Returns the database field type as a string. If there is an error, the table doesn't exist, the field doesn't exist or some other reason a null string is returned.} Function TypeField(DatabaseName, TableName, FieldName: String): String; {!~ Returns the database field type as a string. If there is an error a null string is returned.} Function TypeFieldFromDataSet(DataSet: TDataSet; FieldName: String): String; implementation Uses ads_Strg, StdCtrls, Controls, Forms, SysUtils, Dialogs; Type {!~ TPanel_Cmp_Sec_ads } TPanel_Cmp_Sec_ads = class(TPanel) Public procedure ResizeShadowLabel(Sender: TObject); End; {!~ TPanel_Cmp_Sec_ads.ResizeShadowLabel } //Unit Description UnitIndex Master Index
procedure TPanel_Cmp_Sec_ads.ResizeShadowLabel( Sender : TObject); Var PH, PW : Integer; LH, LW : Integer; begin PH := TPanel(Sender).Height; PW := TPanel(Sender).Width; LH := TLabel(Controls[0]).Height; LW := TLabel(Controls[0]).Width; TLabel(Controls[0]).Top := ((PH-LH) div 2)-3; TLabel(Controls[0]).Left := ((Pw-Lw) div 2)-3; End; Type {!~ TEditKeyFilter } TEditKeyFilter = Class(TEdit) Published {!~ Throws away all keys except 0-9,-,+,.} Procedure OnlyNumbers(Sender: TObject; var Key: Char); {!~ Throws away all keys except 0-9} Procedure OnlyNumbersAbsolute(Sender: TObject; var Key: Char); {!~ Throws away all keys except a-z and A-Z} Procedure OnlyAToZ(Sender: TObject; var Key: Char); End; {!~ TEditKeyFilter.OnlyNumbers Throws away all keys except 0-9,-,+,.} //Unit Description UnitIndex Master Index
Procedure TEditKeyFilter.OnlyNumbers(Sender: TObject; var Key: Char); Begin KeyPressOnlyNumbers(Key); End; {!~ TEditKeyFilter.OnlyNumbersAbsolute Throws away all keys except 0-9} //Unit Description UnitIndex Master Index
Procedure TEditKeyFilter.OnlyNumbersAbsolute(Sender: TObject; var Key: Char); Begin KeyPressOnlyNumbersAbsolute(Key); End; {!~ TEditKeyFilter.OnlyAToZ Throws away all keys except a-z and A-Z} //Unit Description UnitIndex Master Index
Procedure TEditKeyFilter.OnlyAToZ(Sender: TObject; var Key: Char); Begin KeyPressOnlyAToZ(Key); End; {!~ AddTables Add source table to destination table} //Unit Description UnitIndex Master Index
Function AddTables( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; Var BMode : TBatchMode; Begin If IsTableKeyed(DestDatabaseName,DestinationTable) Then Begin If IsTableKeyed(SourceDatabaseName,SourceTable) Then Begin BMode := BatAppendUpdate; End Else Begin BMode := BatAppend; End; End Else Begin BMode := BatAppend; End; Result := DBRecordMove(SourceDatabaseName,SourceTable, DestDatabaseName,DestinationTable,BMode); End; {!~ CreateTableFromQuery Creates a new table from a Query. Complex joins can be output to a new table.} //Unit Description UnitIndex Master Index
Function CreateTableFromQuery( Query: TQuery; NewTableName, TableDatabaseName: String): Boolean; Begin Result := DBCreateTableFromQuery(Query,NewTableName,TableDatabaseName); End; {!~ DBAddQueryToTable Add source query to destination table} //Unit Description UnitIndex Master Index
Procedure DBAddQueryToTable( DataSet : TQuery; const DestDatabaseName, DestinationTable: string); var DTable : TTable; BMove : TBatchMove; begin DTable := TTable.Create(nil); BMove := TBatchMove.Create(nil); Try DataSet.Active := True; DTable.DatabaseName := DestDatabaseName; DTable.TableName := DestinationTable; DTable.Active := True; BMove.AbortOnKeyViol := False; BMove.AbortOnProblem := False; BMove.ChangedTableName := 'CTable'; BMove.Destination := DTable; BMove.KeyViolTableName := 'KTable'; BMove.Mode := batAppend; BMove.ProblemTableName := 'PTable'; BMove.Source := DataSet; BMove.Execute; Finally DTable.Active := False; DTable.Free; BMove.Free; End; End; {!~ DBAddTables Add source table to destination table} //Unit Description UnitIndex Master Index
Function DBAddTables( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; begin Result := AddTables(SourceDatabaseName,SourceTable, DestDatabaseName,DestinationTable); End; {!~ DBCopyFieldAToB Copies Field A To Field B.} //Unit Description UnitIndex Master Index
function DBCopyFieldAToB( DatabaseName, TableName, SourceField, DestField: String): Boolean; var Query : TQuery; CursorWas : TCursor; Sess : TSession; begin CursorWas := Screen.Cursor; Sess := DBSessionCreateNew; Sess.Active := True; Query := TQuery.Create(sess); Query.SessionName := Sess.SessionName; Sess.Active := True; Query.Active := False; Query.RequestLive := True; try Result := False; Query.DatabaseName := DatabaseName; Query.SQL.Clear; Query.SQL.Add('Select '); Query.SQL.Add(SourceField+','); Query.SQL.Add(DestField); Query.SQL.Add('From '+TableName); Query.Open; Query.First; While Not Query.EOF Do Begin //ProgressScreenCursor; Try Query.Edit; Query.FieldByName(DestField).AsString := Query.FieldByName(SourceField).AsString; Query.Post; Except End; Query.Next; End; Result := True; finally Query.Free; Screen.Cursor := CursorWas; Sess.Active := False; end; End; {!~ DBCopyTable Copies SourceTable To DestTable. If DestTable exists it is deleted} //Unit Description UnitIndex Master Index
Function DBCopyTable( SourceDatabaseName, SourceTable, DestDatabaseName, DestTable: String): Boolean; Begin Result := DBRecordMove(SourceDatabaseName,SourceTable, DestDatabaseName,DestTable,batCopy); End; {!~ DBCopyTableAToB Copies Table A To Table B. If Table B exists it is emptied} //Unit Description UnitIndex Master Index
Function DBCopyTableAToB( SourceDatabaseName, SourceTable, DestDatabaseName, DestTable: String): Boolean; begin Result := DBCopyTable( SourceDatabaseName, SourceTable, DestDatabaseName, DestTable); End; {!~ DBCopyTableToServer Copies a table from the source to the destination. If the destination table exists the function will not throw an error, the existing table will be replaced with the new table. example: This is a very powerful migration utility. It can be used to copy tables from and to any location. The following example copies the DBDemos "Customer.db" table to a Sybase client server database. DBCopyTableToServer( 'DBDemos', 'Customer.Db', 'SybaseDb', 'Customer'); } //Unit Description UnitIndex Master Index
Function DBCopyTableToServer( SourceDatabaseName : String; SourceTableName : String; DestDatabaseName : String; DestTableName : String): Boolean; Begin Result := False; Try If DBCreateTableBorrowStr( SourceDatabaseName, SourceTableName, DestDatabaseName, DestTableName) Then Begin If AddTables( SourceDatabaseName, SourceTableName, DestDatabaseName, DestTableName) Then Begin Result := True; End; End; Except On E : Exception Do Begin ShowMessage('DBCopyTableToServer Error: '+E.Message); Result := False; End; End; End; {!~ DBCreateTableBorrowStr Creates an empty table with indices by borrowing the structure of a source table. Source and destination can be remote or local tables. If the destination table exists the function will not throw an error, the existing table will be replaced with the new table. example: This is a very powerful migration utility. The function creates an empty table with indices by borrowing the structure of a source table. Source and destination can be remote or local tables. If the destination table exists the function will not throw an error, the existing table will be replaced with the new table. The following example creates an empty version of the DBDemos "Customer.Db" table on a Sybase Client Server Database. DBCreateTableBorrowStr( 'DBDemos', 'Customer.Db', 'SybaseDb', 'Customer'); } //Unit Description UnitIndex Master Index
Function DBCreateTableBorrowStr( SourceDatabaseName : String; SourceTableName : String; DestDatabaseName : String; DestTableName : String): Boolean; Var S : TTable; D : TTable; i : Integer; j : Integer; IMax : Integer; IndexName : String; IndexFields : String; IndexFields2 : String; Q : TQuery; IDXO : TIndexOptions; Begin S := TTable.Create(nil); D := TTable.Create(nil); Try Try S.Active := False; S.DatabaseName := SourceDatabaseName; S.TableName := SourceTableName; S.TableType := ttDefault; S.Active := True; D.DatabaseName := DestDatabaseName; D.TableName := DestTableName; D.TableType := ttDefault; D.FieldDefs.Assign(S.FieldDefs); D.CreateTable; {Similar method could be used to create the indices} {D.IndexDefs.Assign(S.IndexDefs);} S.IndexDefs.Update; D.IndexDefs.Update; D.IndexDefs.Clear; D.IndexDefs.Update; For i := 0 To S.IndexDefs.Count - 1 Do Begin If Pos('.DB',UpperCase(DestTableName)) > 0 Then Begin {Paradox or DBase Tables} If S.IndexDefs.Items[i].Name = '' Then Begin If Pos('.DB',UpperCase(DestTableName)) = 0 Then Begin IndexName := DestTableName+IntToStr(i); End Else Begin IndexName := ''; End; End Else Begin IndexName := DestTableName+IntToStr(i); End; IndexFields := S.IndexDefs.Items[i].Fields; D.AddIndex(IndexName,IndexFields,S.IndexDefs.Items[i].Options); D.IndexDefs.Update; End Else Begin {Non Local Tables} Q := TQuery.Create(nil); Try S.IndexDefs.Update; D.IndexDefs.Update; D.IndexDefs.Clear; D.IndexDefs.Update; IMax := S.IndexDefs.Count - 1; For j := 0 To IMax Do Begin Q. Active := False; Q.DatabaseName := DestDatabaseName; IndexName := DestTableName+IntToStr(j); IndexFields := S.IndexDefs.Items[j].Fields; IndexFields2 := ReplaceCharInString(IndexFields,';',','); Q.SQL.Clear; Q.SQL.Add('Create'); If ixUnique in S.IndexDefs.Items[j].Options Then Begin Q.SQL.Add('Unique'); End; If ixDescending in S.IndexDefs.Items[j].Options Then Begin Q.SQL.Add('Desc'); End Else Begin Q.SQL.Add('Asc'); End; Q.SQL.Add('Index'); Q.SQL.Add(IndexName); Q.SQL.Add('On'); Q.SQL.Add(DestTableName); Q.SQL.Add('('); Q.SQL.Add(IndexFields2); Q.SQL.Add(')'); Try Q.ExecSql; D.IndexDefs.Update; D.AddIndex(IndexName,IndexFields,S.IndexDefs.Items[j].Options); D.IndexDefs.Update; Except On E : EDBEngineError Do Begin If E.Message = 'Invalid array of index descriptors.' Then Begin Try D.IndexDefs.Update; D.DeleteIndex(IndexName); D.IndexDefs.Update; Except End; End Else Begin Try D.IndexDefs.Update; IDXO := D.IndexDefs.Items[j].Options; Except End; {Msg('DBCreateTableBorrowStr Error: '+E.Message);} End; End; End; End; Finally Q.Free; End; End; End; S.Active := False; Result := True; Finally S.Free; D.Free; End; Except On E : Exception Do Begin ShowMessage('DBCreateTableBorrowStr Error: '+E.Message); Result := False; End; End; End; {!~ DBCreateTableFromQuery Creates a new table from a Query. Complex joins can be output to a new table.} //Unit Description UnitIndex Master Index
Function DBCreateTableFromQuery( Query: TQuery; NewTableName, TableDatabaseName: String): Boolean; var D : TTable; ActiveWas : Boolean; begin D := nil; try {The Source Table} ActiveWas := Query.Active; Query.Active := true; {Create The Destination Table} D := TTable.Create(nil); D.Active := False; D.DatabaseName := TableDatabaseName; D.TableName := NewTableName; D.ReadOnly := False; {Make the table copy} D.BatchMove(Query,batCopy); Query.Active := ActiveWas; Result := True; finally D.Free; end; End; //Unit Description UnitIndex Master Index
Function DBCreateTableFromTTable( Table: TTable; NewTableName, TableDatabaseName: String): Boolean; var D : TTable; ActiveWas : Boolean; begin D := nil; try {The Source Table} ActiveWas := Table.Active; Table.Active := true; {Create The Destination Table} D := TTable.Create(nil); D.Active := False; D.DatabaseName := TableDatabaseName; D.TableName := NewTableName; D.ReadOnly := False; {Make the table copy} D.BatchMove(Table,batCopy); Table.Active := ActiveWas; Result := True; finally D.Free; end; End; {!~ DBDeleteTable Deletes A Table} //Unit Description UnitIndex Master Index
Function DBDeleteTable(const DatabaseName, TableName : string):Boolean; Begin Try If Not IsTable(DatabaseName, TableName) Then Begin Result := False; Exit; End; Result := DBDropTable(DatabaseName, TableName); Except Result := False; End; End; {!~ DBDropTable Drops A Table} //Unit Description UnitIndex Master Index
Function DBDropTable(const DatabaseName, TableName : string):Boolean; var Query : TQuery; begin Result := False; If Not IsTable(DatabaseName, TableName) Then Begin Exit; End; Query := TQuery.Create(nil); try Query.DatabaseName := DatabaseName; Query.SQL.Clear; Query.SQL.Add('Drop Table '); If (Pos('.DB', UpperCase(TableName)) > 0) Or (Pos('.DBF',UpperCase(TableName)) > 0) Then Begin Query.Sql.Add('"'+TableName+'"'); End Else Begin Query.Sql.Add(TableName); End; Result := True; Try Query.ExecSQL; Except Result := False; End; finally Query.Free; end; End; {!~ DBEmptyTable Empties a table of all records} //Unit Description UnitIndex Master Index
Function DBEmptyTable( const DatabaseName, TableName : string): Boolean; var Query : TQuery; begin Query := TQuery.Create(nil); try Query.DatabaseName := DatabaseName; Query.SQL.Clear; If Pos('.DB',UpperCase(TableName)) > 0 Then Query.SQL.Add('DELETE FROM "'+TableName+'"') Else Query.SQL.Add('DELETE FROM '+TableName); Query.ExecSQL; Result := True; finally Query.Free; end; End; {!~ DBFieldNameByNo Returns the field Name as a String. If there is an error, the table doesn't exist, the field doesn't exist or some other reason '' is returned. example: Returns the field Name as a String. If there is an error, the table doesn't exist, the field doesn't exist or some other reason '' is returned. The field number is zero based so the first column would be 0, the 2nd column 1 etc. This example returns "Company" as the name of the 2nd column in the table. "1" is entered as the column number because it is zero based. FieldName := DBFieldNameByNo( 'DBDemos', 'Customer.Db', 1); } //Unit Description UnitIndex Master Index
Function DBFieldNameByNo( DatabaseName : String; TableName : String; FieldNo : Integer): String; Var Table : TTable; Begin Result := ''; If Not IsTable(DatabaseName, TableName) Then Exit; If FieldNo < 0 Then Exit; If FieldNo >= DBNFields(DatabaseName, TableName) Then Exit; Table := TTable.Create(nil); Try Try Table.Active := False; Table.DatabaseName := DatabaseName; Table.TableName := TableName; Table.Active := True; Result := Table.FieldDefs[FieldNo].Name; Except End; Finally Table.Free; End; End; {!~ DBFieldNamesCommonToString Returns Field Names shared by 2 tables as a string. Fields are separated by commas with no trailing comma.} //Unit Description UnitIndex Master Index
Function DBFieldNamesCommonToString( DatabaseName1 : String; TableName1 : String; DatabaseName2 : String; TableName2 : String): String; Var List1 : TStringList; List2 : TStringList; i : Integer; Suffix: String; Begin Result := ''; List1 := TStringList.Create(); List2 := TStringList.Create(); Try DBFieldNamesToTStrings( DatabaseName1, TableName1, List1); For i := 0 To List1.Count - 1 Do Begin List1[i] := UpperCase(List1[i]); End; DBFieldNamesToTStrings( DatabaseName2, TableName2, List2); For i := 0 To List2.Count - 1 Do Begin List2[i] := UpperCase(List2[i]); End; For i := 0 To List1.Count - 1 Do Begin If Result = '' Then Begin Suffix := ''; End Else Begin Suffix := ', '; End; If List2.IndexOf(List1[i]) <> -1 Then Begin Result := Result + Suffix + List1[i]; End; End; Finally List1.Free; List2.Free; End; End; {!~ DBFieldNamesCommonToTStrings Copies Field Names shared by 2 tables to a TStrings object. Returns true if successful. If there is an error, the DatabaseName doesn't exist, the table doesn't exist or some other reason False is returned. } //Unit Description UnitIndex Master Index
Function DBFieldNamesCommonToTStrings( DatabaseName1 : String; TableName1 : String; DatabaseName2 : String; TableName2 : String; Strings : TStrings): Boolean; Var List1 : TStringList; List2 : TStringList; i : Integer; Begin { Result := False;}{zzz} List1 := TStringList.Create(); List2 := TStringList.Create(); Try Strings.Clear; DBFieldNamesToTStrings( DatabaseName1, TableName1, List1); For i := 0 To List1.Count - 1 Do Begin List1[i] := UpperCase(List1[i]); End; DBFieldNamesToTStrings( DatabaseName2, TableName2, List2); For i := 0 To List2.Count - 1 Do Begin List2[i] := UpperCase(List2[i]); End; For i := 0 To List1.Count - 1 Do Begin If List2.IndexOf(List1[i]) <> -1 Then Begin Strings.Add(List1[i]); End; End; Result := True; Finally List1.Free; List2.Free; End; End; {!~ DBFieldNamesToTStrings Copies Table Field Names to a TStrings object, e.g., ListBox1.Items, Memo1.Lines. Returns true if successful. If there is an error, the DatabaseName doesn't exist, the table doesn't exist or some other reason False is returned. example: DBFieldNamesToTStrings copies Table Field Names to a TStrings object, e.g., ListBox1.Items, Memo1.Lines. It returns true if successful, False otherwise. If there is an error, the DatabaseName doesn't exist, the table doesn't exist or some other reason False is returned. In this example the DBDemos "Customer.Db" table Field Names populate a TStringList that is passed as a parameter to the procedure. Procedure TForm1.GetFieldNames( DatabaseName : String; TableName : String; TSL : TStrings); Begin DBFieldNamesToTStrings( DatabaseName, TableName, TSL); End; Procedure TForm1.FormCreate( Begin TSL := TStringList.Create(); GetFieldNames( 'DBDemos', 'Customer.Db', TSL); End; } //Unit Description UnitIndex Master Index
Function DBFieldNamesToTStrings( DatabaseName : String; TableName : String; Strings : TStrings): Boolean; Var Table : TTable; FieldNo : Integer; Begin Result := False; If Not IsTable(DatabaseName, TableName) Then Exit; Table := TTable.Create(nil); Try Try Table.Active := False; Table.DatabaseName := DatabaseName; Table.TableName := TableName; Table.Active := True; Strings.Clear; For FieldNo := 0 To Table.FieldDefs.Count -1 Do Begin Strings.Add(Table.FieldDefs[FieldNo].Name); End; Result := True; Except End; Finally Table.Free; End; End; {!~ DBFieldNo Returns the field Number as an integer. If there is an error, the table doesn't exist, the field doesn't exist or some other reason -1 is returned.} //Unit Description UnitIndex Master Index
Function DBFieldNo(DatabaseName, TableName, FieldName: String): Integer; Var Table : TTable; FieldIndex : Integer; FieldNumber: Integer; Begin Result := -1; If Not IsTable(DatabaseName, TableName) Then Exit; If Not IsField(DatabaseName, TableName, FieldName) Then Exit; Table := TTable.Create(nil); Try Try Table.Active := False; Table.DatabaseName := DatabaseName; Table.TableName := TableName; Table.Active := True; FieldIndex := Table.FieldDefs.IndexOf(FieldName); FieldNumber := Table.FieldDefs[FieldIndex].FieldNo; Result := FieldNumber; Except End; Finally Table.Free; End; End; {!~ DBFieldSize Returns the database field Size as an integer. If there is an error, the table doesn't exist, the field doesn't exist or some other reason 0 is returned.} //Unit Description UnitIndex Master Index
Function DBFieldSize(DatabaseName, TableName, FieldName: String): Integer; Var Table : TTable; FieldIndex : Integer; FieldSize : Integer; Begin Result := 0; If Not IsTable(DatabaseName, TableName) Then Exit; If Not IsField(DatabaseName, TableName, FieldName) Then Exit; Table := TTable.Create(nil); Try Try Table.Active := False; Table.DatabaseName := DatabaseName; Table.TableName := TableName; Table.Active := True; FieldIndex := Table.FieldDefs.IndexOf(FieldName); FieldSize := Table.FieldDefs[FieldIndex].Size; Result := FieldSize; Except End; Finally Table.Free; End; End; {!~ DBFieldType Returns the database field type as a string. If there is an error, the table doesn't exist, the field doesn't exist or some other reason a null string is returned.} //Unit Description UnitIndex Master Index
Function DBFieldType(DatabaseName, TableName, FieldName: String): String; Begin Result := TypeField(DatabaseName, TableName, FieldName); End; {!~ DBFieldTypeByNo Returns the database field type as a string. If there is an error, the table doesn't exist, the field doesn't exist or some other reason a null string is returned.} //Unit Description UnitIndex Master Index
Function DBFieldTypeByNo(DatabaseName, TableName: String; FieldNo: Integer): String; Var Table : TTable; FieldIndex : Integer; FieldType : TFieldType; Begin Result := ''; If Not IsTable(DatabaseName, TableName) Then Exit; Table := TTable.Create(nil); Try Try Table.Active := False; Table.DatabaseName := DatabaseName; Table.TableName := TableName; Table.Active := True; FieldIndex := FieldNo; Try FieldType := Table.FieldDefs[FieldIndex].DataType; Except FieldType := ftUnknown; End; {TFieldType Possible values are ftUnknown, ftString, ftSmallint, ftInteger, ftWord, ftBoolean, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime, ftBytes, ftVarBytes, ftBlob, ftMemo or ftGraphic} If FieldType=ftUnknown Then Result := 'Unknown'; If FieldType=ftString Then Result := 'String'; If FieldType=ftSmallInt Then Result := 'SmallInt'; If FieldType=ftInteger Then Result := 'Integer'; If FieldType=ftWord Then Result := 'Word'; If FieldType=ftBoolean Then Result := 'Boolean'; If FieldType=ftFloat Then Result := 'Float'; If FieldType=ftCurrency Then Result := 'Currency'; If FieldType=ftBCD Then Result := 'BCD'; If FieldType=ftDate Then Result := 'Date'; If FieldType=ftTime Then Result := 'Time'; If FieldType=ftDateTime Then Result := 'DateTime'; If FieldType=ftBytes Then Result := 'Bytes'; If FieldType=ftVarBytes Then Result := 'VarBytes'; If FieldType=ftBlob Then Result := 'Blob'; If FieldType=ftMemo Then Result := 'Memo'; If FieldType=ftGraphic Then Result := 'Graphic'; Except End; Finally Table.Free; End; End; {!~ DBGlobalStringFieldChange Replace all the values in a field that match a condition value with a new value} //Unit Description UnitIndex Master Index
procedure DBGlobalStringFieldChange( const DatabaseName, TableName, FieldName, NewValue : string); begin DBGlobalStringFieldChangeWhere( DatabaseName, TableName, FieldName, '', NewValue); End; {!~ DBGlobalStringFieldChangeWhere Replace all the values in a field with a new value} //Unit Description UnitIndex Master Index
procedure DBGlobalStringFieldChangeWhere( const DatabaseName, TableName, FieldName, CurrentValue, NewValue : string); var Query : TQuery; begin Query := TQuery.Create(nil); Try Query.Active := False; Query.DatabaseName := DatabaseName; Query.RequestLive := True; Query.RequestLive := True; Query.Sql.Clear; Query.Sql.Add('UpDate'); Query.Sql.Add('"'+TableName+'"'); Query.Sql.Add('Set'); Query.Sql.Add( '"'+TableName+'"."'+FieldName+'"'+ ' = '+ '"'+NewValue+'"'); Query.Sql.Add('Where'); Query.Sql.Add( '"'+TableName+'"."'+FieldName+'"'+ ' <> '+ '"'+NewValue+'"'); If Not (CurrentValue = '') Then Begin Query.Sql.Add('And '); Query.Sql.Add( '"'+TableName+'"."'+FieldName+'"'+ ' = '+ '"'+CurrentValue+'"'); End; Query.ExecSql; Query.Active := False; Finally Query.Free; End; End; {!~ DBGlobalStringFieldChangeWhere2 Replace values in a field (NewValueField) with NewValue based on a where condition in CurrentValueField with a value of CurrentValue} //Unit Description UnitIndex Master Index
procedure DBGlobalStringFieldChangeWhere2( const DatabaseName, TableName, NewValueField, NewValue, CurrentValueField, CurrentValue: string); var Query : TQuery; CValueQuoted : String; begin Query := TQuery.Create(nil); Try CValueQuoted := DBSqlValueQuoted( DatabaseName, TableName, CurrentValueField, CurrentValue); Query.Active := False; Query.DatabaseName := DatabaseName; Query.RequestLive := True; Query.RequestLive := True; Query.Sql.Clear; Query.Sql.Add('UpDate'); Query.Sql.Add('"'+TableName+'"'); Query.Sql.Add('Set'); Query.Sql.Add( '"'+TableName+'"."'+NewValueField+'"'+ ' = '+ '"'+NewValue+'"'); If Not (CurrentValue = '') Then Begin Query.Sql.Add('Where'); Query.Sql.Add( '"'+TableName+'"."'+CurrentValueField+'"'+ ' = '+ CValueQuoted); End; {Query.Sql.SaveToFile(ExtractFileNameNoExt(TableName)+'.sql');} Query.ExecSql; Query.Active := False; Finally Query.Free; End; End; {!~ DBInsertMatchingFields Inserts matching fields in a destination table. Source Table records are deleted if the record was inserted properly. Records unsuccessfully inserted are retained and the problems recorded in the ErrorField.} //Unit Description UnitIndex Master Index
Function DBInsertMatchingFields( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable, ErrorField: string): Boolean; Var S : TTable; T : TTable; D : TQuery; i,j,K : Integer; Keys : TStringList; KeyValues : TStringList; CommonFields : TStringList; {WhereAnd : String;}{zzz} {CurField : String;}{zzz} {CurValue_S : String;}{zzz} {DFieldType : String;}{zzz} EMessage : String; ESuccess : String; Begin Result := False; ESuccess := 'Successful'; S := TTable.Create(nil); D := TQuery.Create(nil); T := TTable.Create(nil); Keys := TStringList.Create(); CommonFields := TStringList.Create(); KeyValues := TStringList.Create(); Try Try D.Active := False; D.DatabaseName := DestDatabaseName; DBKeyFieldNamesToTStrings( SourceDatabaseName, SourceTable, Keys); DBFieldNamesCommonToTStrings( SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable, CommonFields); S.Active := False; S.DatabaseName := SourceDatabaseName; S.TableName := SourceTable; S.Active := True; S.First; While Not S.EOF Do Begin Try {Capture the key field values} KeyValues.Clear; For j := 0 To Keys.Count - 1 Do Begin KeyValues.Add(S.FieldByName(Keys[j]).AsString); End; If IsRecord( DestDatabaseName, DestinationTable, Keys, KeyValues) Then Begin {The record already exists in the destination table} Try S.Edit; S.FieldByName(ErrorField).AsString := 'Error-Insert-Record already exists in destination table'; S.Post; Except End; S.Next; Continue; End Else Begin {The record does not exist in the destination table} Try EMessage := ESuccess; S.Edit; S.FieldByName(ErrorField).AsString := EMessage; S.Post; Except End; End; Try T.Active := False; T.DatabaseName := DestDatabaseName; T.TableName := DestinationTable; T.Active := True; T.Insert; For i := 0 To CommonFields.Count - 1 Do Begin T.FieldByName(CommonFields[i]).AsString := S.FieldByName(CommonFields[i]).AsString; End; T.Post; Except If EMessage = ESuccess Then Begin EMessage := 'Error-Insert- Keys:'; For K := 0 To Keys.Count -1 Do Begin EMessage := EMessage + Keys[K]+'='+S.FieldByName(Keys[K]).AsString+', '; End; End; Try S.Edit; S.FieldByName(ErrorField).AsString := EMessage; S.Post; Except End; End; Except If EMessage = ESuccess Then Begin EMessage := 'Error-Insert- Keys:'; For K := 0 To Keys.Count -1 Do Begin EMessage := EMessage + Keys[K]+'='+S.FieldByName(Keys[K]).AsString+', '; End; End; Try S.Edit; S.FieldByName(ErrorField).AsString := EMessage; S.Post; Except End; End; S.Next; End; If Not IsField(SourceDatabaseName, SourceTable, ErrorField) Then Begin ShowMessage('Cannot delete records from '+ SourceTable+' table because '+ErrorField+ ' Field does not exist'); End Else Begin D.Active := False; D.RequestLive := True; D.DatabaseName := SourceDatabaseName; D.Sql.Clear; D.Sql.Add('Delete From '+SourceTable); D.Sql.Add('Where'); D.Sql.Add(ErrorField+' = "'+ESuccess+'"'); D.ExecSql; D.Active := False; End; Result := True; Except If EMessage = ESuccess Then Begin EMessage := 'Error-Process Level- Keys:'; For K := 0 To Keys.Count -1 Do Begin EMessage := EMessage + Keys[K]+'='+S.FieldByName(Keys[K]).AsString+', '; End; End Else Begin EMessage := EMessage + 'Process Error Also'; End; Try S.Edit; S.FieldByName(ErrorField).AsString := EMessage; S.Post; Except End; End; Finally S.Free; D.Free; T.Free; Keys.Free; CommonFields.Free; KeyValues.Free; End; End; {!~ DBKeyFieldNamesToTStrings Copies Table Key Field Names to a TStrings object. Returns the true if successful. If there is an error, the DatabaseName doesn't exist, the table doesn't exist or some other reason False is returned. } //Unit Description UnitIndex Master Index
Function DBKeyFieldNamesToTStrings( DatabaseName : String; TableName : String; Strings : TStrings): Boolean; Var Table : TTable; FieldNo : Integer; Begin Result := False; If Not IsTable(DatabaseName, TableName) Then Exit; Table := TTable.Create(nil); Try Try Table.Active := False; Table.DatabaseName := DatabaseName; Table.TableName := TableName; Table.Active := True; Strings.Clear; For FieldNo := 0 To Table.FieldDefs.Count -1 Do Begin If IsFieldKeyed( DatabaseName, TableName, Table.FieldDefs[FieldNo].Name) Then Begin Strings.Add(Table.FieldDefs[FieldNo].Name); End; End; Result := True; Except End; Finally Table.Free; End; End; {!~ DBLookUpDialog Presents a lookup Dialog to the user. The selected value is returned if the user presses OK and the Default value is returned if the user presses Cancel unless the TStringList is nil in which case a blank string is returned} //Unit Description UnitIndex Master Index
Function DBLookUpDialog( Const DataBaseName : String; Const TableName : String; Const FieldName : String; Const SessionName : String; Const DefaultValue : String; const DialogCaption : string; const InputPrompt : string; const DialogWidth : Integer ): String; Begin Result := DialogDBLookUp( DataBaseName, TableName, FieldName, SessionName, DefaultValue, DialogCaption, InputPrompt, DialogWidth ); End; {!~ DBMedianSingle Returns the median value for a column in a table as type single} //Unit Description UnitIndex Master Index
Function DBMedianSingle( const DatabaseName, TableName, FieldName, WhereString : string): Single; Var Query : TQuery; NRecords : LongInt; NMedian : LongInt; Value1 : Single; Value2 : Single; Begin Query := TQuery.Create(nil); Try {Get the number of values} Query.Active := False; Query.DatabaseName := DatabaseName; Query.SQL.Clear; Query.SQL.Add('Select Count(*)'); Query.SQL.Add('From'); If (Pos('.DB', UpperCase(TableName)) > 0) Or (Pos('.DBF',UpperCase(TableName)) > 0) Then Begin Query.Sql.Add('"'+TableName+'"'); End Else Begin Query.Sql.Add(TableName); End; Query.SQL.Add('Where'); Query.SQL.Add(FieldName+' is not null'); If Not (WhereString = '') Then Begin Query.SQL.Add('And'); Query.SQL.Add(WhereString); End; Query.Active := True; NRecords := Query.Fields[0].AsInteger; NMedian := NRecords div 2; {Get the median value} Query.Active := False; Query.DatabaseName := DatabaseName; Query.SQL.Clear; Query.SQL.Add('Select'); Query.SQL.Add(FieldName); Query.SQL.Add('From'); If (Pos('.DB', UpperCase(TableName)) > 0) Or (Pos('.DBF',UpperCase(TableName)) > 0) Then Begin Query.Sql.Add('"'+TableName+'"'); End Else Begin Query.Sql.Add(TableName); End; Query.SQL.Add('Where'); Query.SQL.Add(FieldName+' is not null'); If Not (WhereString = '') Then Begin Query.SQL.Add('And'); Query.SQL.Add(WhereString); End; Query.SQL.Add('Order By'); Query.SQL.Add(FieldName); Query.Active := True; Query.First; If Odd(NRecords) Then Begin {Odd Number of records} Query.MoveBy(NMedian); Result := Query.FieldByName(FieldName).AsFloat; End Else Begin {Even Number of records} Query.MoveBy(NMedian-1); Value1 := Query.FieldByName(FieldName).AsFloat; Query.Next; Value2 := Query.FieldByName(FieldName).AsFloat; Result := (Value1+Value2)/2; End; Finally Query.Free; End; End; {!~ DBMoveTable Moves SourceTable From SourceDatabaseName To DestDatabasename. If a table exists with the same name at DestDatabaseName it is overwritten.} //Unit Description UnitIndex Master Index
Function DBMoveTable( SourceTable, SourceDatabaseName, DestDatabaseName: String): Boolean; Begin Result := True; Try {First Copy The Source Table To The New Table} If Not DBCopyTable( SourceDatabaseName, SourceTable, DestDatabaseName, SourceTable) Then Begin Result := False; Exit; End; {Now Drop The Source Table} If Not DBDropTable(SourceDatabaseName, SourceTable) Then Begin Result := False; Exit; End; Except Result := False; End; End; {!~ DBNFields Returns the number of fields in a table} //Unit Description UnitIndex Master Index
Function DBNFields(DatabaseName, TableName: String): Integer; Begin Result := NFields(DatabaseName, TableName); End; {!~ DBNextAlphaKey Returns the next key value when the table keys are numbers as strings, e.g., ' 12' key would return ' 13'} //Unit Description UnitIndex Master Index
Function DBNextAlphaKey(DatabaseName, TableName, FieldName: String):String; Var Query : TQuery; CurrentMax_S : String; CurrentLen_I : Integer; CurrentMax_I : LongInt; NewMax_S : String; NewMax_I : LongInt; Counter : Integer; Begin Result := ''; Query := TQuery.Create(nil); Try Result := '1'; CurrentMax_S := ''; CurrentMax_I := 0; CurrentLen_I := 0; NewMax_S := '1'; Query.DatabaseName := DatabaseName; Query.SQL.Clear; Query.SQL.Add('Select '); Query.SQL.Add('Max('+FieldName+')'); Query.SQL.Add('From '+TableName); Query.Open; Try CurrentMax_S := Query.Fields[0].AsString; Except End; Try CurrentLen_I := Length(CurrentMax_S); Except End; Try CurrentMax_I := StrToInt(CurrentMax_S); Except End; NewMax_I := CurrentMax_I + 1; NewMax_S := IntToStr(NewMax_I); For Counter := 1 To CurrentLen_I Do Begin If Length(NewMax_S) >= CurrentLen_I Then Break; NewMax_S := ' '+NewMax_S; End; Result := NewMax_S; Finally Query.Free; End; End; {!~ DBNextInteger Returns the next key value when the table keys are integers, e.g., 12 key would return 13} //Unit Description UnitIndex Master Index
Function DBNextInteger( DatabaseName, TableName, FieldName: String):LongInt; Var Query : TQuery; CurrentMax : LongInt; NewMax : LongInt; Begin CurrentMax := 0; Query := TQuery.Create(nil); Try Query.DatabaseName := DatabaseName; Query.SQL.Clear; Query.SQL.Add('Select '); Query.SQL.Add('Max('+FieldName+')'); Query.SQL.Add('From '); If (Pos('.DB', UpperCase(TableName)) > 0) Or (Pos('.DBF',UpperCase(TableName)) > 0) Then Begin Query.Sql.Add('"'+TableName+'"'); End Else Begin Query.Sql.Add(TableName); End; Query.Open; Try CurrentMax := Query.Fields[0].AsInteger; Except End; NewMax := CurrentMax + 1; Result := NewMax; Finally Query.Free; End; End; {!~ DBParadoxCreateNKeys ReKeys a Paradox Table to the first N fields} //Unit Description UnitIndex Master Index
Function DBParadoxCreateNKeys( DatabaseName : String; TableName : String; NKeys : Integer): Boolean; Var T : TTable; T2 : TTable; i : Integer; TempDBName : String; TempTblNam : String; TempTblStub: String; KeysString : String; Begin Result := False; {Select a temporary table name} TempTblStub := 'qrz'; TempDBName := DatabaseName; TempTblNam := ''; For i := 1 To 100 Do Begin TempTblNam := TempTblStub+StringPad(IntToStr(i),'0',3,False)+'.Db'; If Not IsTable(TempDBName,TempTblNam) Then Begin Break; End Else Begin If i = 100 Then Begin DBDeleteTable( TempDBName, TempTblNam); End; End; End; T := TTable.Create(nil); T2 := TTable.Create(nil); Try Try T.Active := False; T.DatabaseName := DatabaseName; T.TableName := TableName; T.Active := True; T2.Active := False; T2.DatabaseName := TempDBName; T2.TableName := TempTblNam; T2.FieldDefs.Assign(T.FieldDefs); T2.IndexDefs.Clear; KeysString := ''; For i := 0 To NKeys - 1 Do Begin If i > 0 Then Begin KeysString := KeysString + ';'; End; KeysString := KeysString + DBFieldNameByNo( DatabaseName, TableName, i); End; T2.IndexDefs.Add('',KeysString,[ixPrimary]); T2.CreateTable; T2.Active := False; T.Active := False; AddTables( DatabaseName, TableName, TempDBName, TempTblNam); DBDeleteTable(DatabaseName,TableName); T2.Active := True; T.DatabaseName := DatabaseName; T.TableName := TableName; T.FieldDefs.Assign(T2.FieldDefs); T.IndexDefs.Clear; T.IndexDefs.Add('',KeysString,[ixPrimary]); T.CreateTable; T2.Active := False; T.Active := False; AddTables( TempDBName, TempTblNam, DatabaseName, TableName); DBDeleteTable( TempDBName, TempTblNam); Result := True; Except ShowMessage('Error in Function DBParadoxCreateNKeys'); End; Finally T.Free; T2.Free; End; End; {!~ DBReNameTable ReNames a table} //Unit Description UnitIndex Master Index
Function DBReNameTable( DatabaseName, TableNameOld, TableNameNew: String): Boolean; Begin Result := True; Try If Not IsTable(DatabaseName, TableNameOld) Then Begin Result := False; Exit; End; {First Copy The Source Table To The New Table} If Not DBCopyTable( DatabaseName, TableNameOld, DatabaseName, TableNameNew) Then Begin Result := False; Exit; End; {Now Drop The Source Table} If Not DBDropTable(DatabaseName, TableNameOld) Then Begin Result := False; Exit; End; Except Result := False; End; End; {!~ DBRecordMove Applies BatchMode Types As Appropriate To Source and Destination Tables} //Unit Description UnitIndex Master Index
Function DBRecordMove( SourceDatabaseName, SourceTable, DestDatabaseName, DestTable: String; BMode: TBatchMode): Boolean; var S : TTable; D : TTable; B : TBatchMove; begin S := TTable.Create(nil); D := TTable.Create(nil); B := TBatchMove.Create(nil); try {Create The Source Table} S.Active := False; S.DatabaseName := SourceDatabaseName; S.ReadOnly := False; S.TableName := SourceTable; S.Active := true; {Create The Destination Table} D.Active := False; D.DatabaseName := DestDatabaseName; D.TableName := DestTable; D.ReadOnly := False; {Make the table copy} B.AbortOnKeyViol := False; B.AbortOnProblem := False; B.Destination := D; B.Source := S; B.Mode := BMode; Try B.Execute; Except End; Result := True; finally S.Free; D.Free; B.Free; end; End; {!~ DBSchemaSame Returns True If The Tables Have Identical Structures, False Otherwise. If 1 Local Table is involved then Indices are ignored!!!!!!} //Unit Description UnitIndex Master Index
Function DBSchemaSame(const DatabaseName1, Table1, DatabaseName2, Table2: string): Boolean; Begin Result := IsStructureSame(DatabaseName1,Table1,DatabaseName2,Table2); End; {!~ DBSessionCreateNew Creates a new TSession object.} {$IFDEF WIN32} //Unit Description UnitIndex Master Index
Function DBSessionCreateNew: TSession; {$ENDIF WIN32} {$IFDEF WIN32} Var List : TStringList; Seed : String; i : Integer; Ses : String; Begin Seed := 'Session'; Ses := Seed+'0'; List := TStringList.Create; Try Sessions.GetSessionNames(List); For i := 0 To 1000 Do Begin Ses := Seed + IntToStr(i); If List.IndexOf(Ses) = -1 Then Break; End; Result := Sessions.OpenSession(Ses); Finally List.Free; End; End; {$ENDIF} {!~ DBSqlValueQuoted Returns a value for use in a sql where clause with the appropriate Quoting of the value based on its datatype. If an error occurs the original string value is returned unchanged} //Unit Description UnitIndex Master Index
Function DBSqlValueQuoted( const DatabaseName, TableName, FieldName, FieldValue: string): String; Var DataType : String; Begin Result := FieldValue; Try DataType := DBFieldType(DatabaseName, TableName, FieldName); If (DataType = 'String') Or (DataType = 'DateTime') Or (DataType = 'Date') Or (DataType = 'Time') Then Begin If DataType <> 'String' Then Begin If FieldValue = '' Then Begin Result := ' null '; End Else Begin Result := '"'+FieldValue+'"'; End; End Else Begin Result := '"'+FieldValue+'"'; End; End Else Begin Result := FieldValue; End; Except End; End; {!~ DBSubtractTable Subtracts the records in the source table from the destination table} //Unit Description UnitIndex Master Index
Function DBSubtractTable( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; Begin Result := SubtractTable(SourceDatabaseName,SourceTable, DestDatabaseName,DestinationTable); End; {!~ DBTrimBlanksLeft Trims blank spaces from the Left of the string} //Unit Description UnitIndex Master Index
Function DBTrimBlanksLeft( DatabaseName : String; TableName : String; FieldName : String): Boolean; Var Q : TQuery; S : String; Begin { Result := False;}{zzz} Q := TQuery.Create(nil); Try Q.Active := False; Q.DatabaseName := DatabaseName; Q.RequestLive := True; Q.Sql.Clear; Q.Sql.Add('Select'); Q.Sql.Add('*'); Q.Sql.Add('From'); Q.Sql.Add('"'+TableName+'"'); Q.Active := True; Q.First; While Not Q.EOF Do Begin S := Q.FieldByName(FieldName).AsString; S := TrimBlanksLeft(S); S := TrimBlanksLeft(S); Q.Edit; Q.FieldByName(FieldName).AsString := S; Q.Post; Q.Next; End; Result := True; Finally Q.Free; End; End; {!~ DBTrimBlanksRight Trims blank spaces from the right of the string} //Unit Description UnitIndex Master Index
Function DBTrimBlanksRight( DatabaseName : String; TableName : String; FieldName : String): Boolean; Var Q : TQuery; S : String; Begin { Result := False;}{zzz} Q := TQuery.Create(nil); Try Q.Active := False; Q.DatabaseName := DatabaseName; Q.RequestLive := True; Q.Sql.Clear; Q.Sql.Add('Select'); Q.Sql.Add('*'); Q.Sql.Add('From'); Q.Sql.Add('"'+TableName+'"'); Q.Active := True; Q.First; While Not Q.EOF Do Begin S := Q.FieldByName(FieldName).AsString; S := TrimBlanksRight(S); S := TrimBlanksRight(S); Q.Edit; Q.FieldByName(FieldName).AsString := S; Q.Post; Q.Next; End; Result := True; Finally Q.Free; End; End; {!~ DBUpdateMatchingFields Updates matching fields in a destination table. Source Table records are deleted if the record was updated properly. Records unsuccessfully updated are retained and the problems recorded in the ErrorField.} //Unit Description UnitIndex Master Index
Function DBUpdateMatchingFields( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable, ErrorField: string; MsgPanel: TPanel; FilePath: String): Boolean; Var S : TTable; D : TQuery; U : TQuery; i,j,K,m : Integer; Keys : TStringList; KeysType : TStringList; KeysQuotes : TStringList; KeysSpaces : TStringList; KeysWhere1 : TStringList; KeysUpdate1 : TStringList; KeysWhere2 : TStringList; KeyWhere1 : String; KeyWhere2 : String; KeyUpdate1 : String; NonKeys : TStringList; NonKeysType : TStringList; NonKeysQuotes : TStringList; NonKeysSpaces : TStringList; NonKeysStr : TStringList; NonKeysString : String; CommonFields : TStringList; UpdateString : String; WhereAnd : String; CurField : String; CurValue_S : String; CurString : String; CurStrings : String; DFieldType : String; EMessage : String; ESuccess : String; DFromString : String; TimeLog : TStringList; SetString : String; Begin ESuccess := 'Successful'; S := TTable.Create(nil); D := TQuery.Create(nil); U := TQuery.Create(nil); Keys := TStringList.Create(); KeysSpaces := TStringList.Create(); KeysType := TStringList.Create(); KeysQuotes := TStringList.Create(); TimeLog := TStringList.Create(); CommonFields := TStringList.Create(); NonKeys := TStringList.Create(); NonKeysQuotes:= TStringList.Create(); NonKeysType := TStringList.Create(); NonKeysSpaces:= TStringList.Create(); NonKeysStr := TStringList.Create(); KeysWhere1 := TStringList.Create(); KeysUpdate1 := TStringList.Create(); KeysWhere2 := TStringList.Create(); NonKeysString:= ''; SetString := 'Set '; TimeLog.Clear; Try Try DBFieldNamesCommonToTStrings( SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable, CommonFields); For i := 0 To CommonFields.Count - 1 Do Begin CommonFields[i] := UpperCase(CommonFields[i]); End; D.Active := False; D.DatabaseName := DestDatabaseName; U.Active := False; U.DatabaseName := DestDatabaseName; UpdateString := 'Update '; If Pos('.DB',UpperCase(DestinationTable)) > 0 Then Begin UpdateString := UpDateString + '"'+DestinationTable+'"'; End Else Begin UpdateString := UpDateString + DestinationTable + ''; End; DBKeyFieldNamesToTStrings(SourceDatabaseName,SourceTable,Keys); KeysSpaces.Clear; KeysType.Clear; KeysQuotes.Clear; For i := 0 To Keys.Count - 1 Do Begin Keys[i] := UpperCase(Keys[i]); If Pos(' ',Keys[i]) > 0 Then Begin KeysSpaces.Add('YES'); End Else Begin KeysSpaces.Add('NO'); End; DFieldType := DBFieldType( SourceDatabaseName, SourceTable, Keys[i]); KeysType.Add(DFieldType); If (DFieldType = 'String') Or (DFieldType = 'DateTime') Or (DFieldType = 'Date') Or (DFieldType = 'Time') Then Begin KeysQuotes.Add('YES'); End Else Begin KeysQuotes.Add('NO'); End; End; NonKeys.Clear; NonKeysQuotes.Clear; NonKeysType.Clear; NonKeysSpaces.Clear; For i := 0 To CommonFields.Count - 1 Do Begin If Keys.IndexOf(CommonFields[i]) = -1 Then Begin NonKeys.Add(CommonFields[i]); DFieldType := DBFieldType( SourceDatabaseName, SourceTable, CommonFields[i]); NonKeysType.Add(DFieldType); If (DFieldType = 'String') Or (DFieldType = 'DateTime') Or (DFieldType = 'Date') Or (DFieldType = 'Time') Then Begin NonKeysQuotes.Add('YES'); End Else Begin NonKeysQuotes.Add('NO'); End; If Pos(' ',CommonFields[i]) > 0 Then Begin NonKeysSpaces.Add('YES'); NonKeysStr.Add('"'+CommonFields[i]+'"'); End Else Begin NonKeysSpaces.Add('NO'); NonKeysStr.Add(CommonFields[i]); End; End; End; S.Active := False; S.DatabaseName := SourceDatabaseName; S.TableName := SourceTable; S.Active := True; S.First; m := 0; NonKeysString := ''; For i := 0 To NonKeysStr.Count - 1 Do Begin If i = (NonKeysStr.Count - 1) Then Begin NonKeysString := NonKeysString + 'a.'+NonKeysStr[i]+'' + ' '; End Else Begin NonKeysString := NonKeysString + 'a.'+NonKeysStr[i]+',' + ' '; End; End; DFromString := 'From '; If Pos('.DB',UpperCase(DestinationTable)) > 0 Then Begin DFromString := DFromString + '"'+DestinationTable+'" a'; End Else Begin DFromString := DFromString + DestinationTable + ' a'; End; WhereAnd := ''; KeysWhere1.Clear; KeysWhere2.Clear; KeysUpdate1.Clear; For j := 0 To Keys.Count -1 Do Begin KeyWhere1 := ''; KeyWhere2 := ''; KeyUpdate1:= ''; If WhereAnd <> '' Then KeyWhere1 := KeyWhere1 + WhereAnd; KeyWhere1 := KeyWhere1 + '('; KeyUpdate1:= KeyUpdate1 + '('; If KeysSpaces[j] = 'YES' Then Begin KeyWhere1 := KeyWhere1 + 'a."'+Keys[j]+'" = '; KeyUpdate1 := KeyUpdate1 + '"'+Keys[j]+'" = '; End Else Begin KeyWhere1 := KeyWhere1 + 'a.'+Keys[j]+' = '; KeyUpdate1 := KeyUpdate1 + Keys[j]+' = '; End; If KeysQuotes[j] = 'YES' Then Begin If KeysType[j] <> 'String' Then Begin {Do not add quotes here, wait till later} End Else Begin KeyWhere1 := KeyWhere1 +'"'; KeyWhere2 := KeyWhere2 +'"'; KeyUpdate1:= KeyUpdate1+'"'; End; End Else Begin KeyWhere1 := KeyWhere1 +''; KeyWhere2 := KeyWhere2 +''; KeyUpdate1:= KeyUpdate1+''; End; KeyWhere2 := KeyWhere2 +')'; KeysWhere1.Add(KeyWhere1); KeysWhere2.Add(KeyWhere2); KeysUpdate1.Add(KeyUpdate1); WhereAnd := 'And '; End; U.Sql.Clear; U.Sql.Add(UpdateString); U.Sql.Add('Temporary SetString'); U.Sql.Add(DFromString); U.Sql.Add('Where'); U.Sql.Add('Temporary Where String'); While Not S.EOF Do Begin Try Inc(m); MsgPanel.Caption := 'Record '+ StringPad( IntToStr(m), ' ', 6, False); MsgPanel.Refresh; Try D.Active := False; D.DatabaseName := DestDatabaseName; D.RequestLive := False; D.Sql.Clear; D.Sql.Add('Select'); D.Sql.Add(NonKeysString); D.Sql.Add(DFromString); D.Sql.Add('Where'); For j := 0 To Keys.Count -1 Do Begin CurValue_S := S.FieldByName(Keys[j]).AsString; If (KeysQuotes[j] = 'YES') And (KeysType[j] <> 'String') Then Begin If CurValue_S = '' Then Begin D.Sql.Add( KeysWhere1[j] + ' null ' + KeysWhere2[j]); End Else Begin D.Sql.Add( KeysWhere1[j] + '"' + CurValue_S + '"' + KeysWhere2[j]); End; End Else Begin D.Sql.Add( KeysWhere1[j] + CurValue_S + KeysWhere2[j]); End; End; D.Active := True; If Not (D.EOF And D.BOF) Then Begin EMessage := ESuccess; S.Edit; S.FieldByName(ErrorField).AsString := EMessage; S.Post; End Else Begin S.Edit; S.FieldByName(ErrorField).AsString := 'No Matching Record'; S.Post; S.Next; Continue; End; Except End; U.Sql.Clear; U.Sql.Add(UpdateString); U.Sql.Add('Set'); For i := 0 To NonKeys.Count - 1 Do Begin CurField := NonKeys[i]; Try With U Do Begin Active := False; SetString := CurField+' = '; CurValue_S := ''; If NonKeysType[i] = 'Float' Then Begin CurValue_S := FormatFloat( '#0.0000000000', S.FieldByName(CurField).AsFloat); End Else Begin CurValue_S := S.FieldByName(CurField).AsString; End; If NonKeysQuotes[i] = 'YES' Then Begin If NonKeysType[i] <> 'String' Then Begin If CurValue_S = '' Then Begin SetString := SetString + ' null '; End Else Begin SetString := SetString + '"'+CurValue_S+'"'; End; End Else Begin SetString := SetString + '"'+CurValue_S+'"'; End; End Else Begin SetString := SetString + CurValue_S; End; SetString := SetString; If i <> (NonKeys.Count - 1) Then SetString := SetString+','; Sql.Add(SetString); End; Except On E : Exception Do Begin If EMessage = ESuccess Then Begin EMessage := 'Error-Field Level- Keys:'; For K := 0 To Keys.Count -1 Do Begin EMessage := EMessage + Keys[K]+'='+S.FieldByName(Keys[K]).AsString+', '; End; EMessage := EMessage + 'FIELDS: '; End; EMessage := {EMessage +} CurField+', '; EMessage := EMessage + E.Message; Try S.Edit; S.FieldByName(ErrorField).AsString := EMessage; S.Post; Except End; End; End; End; CurStrings := ''; WhereAnd := ''; For j := 0 To Keys.Count -1 Do Begin CurStrings := CurStrings + WhereAnd; CurValue_S := S.FieldByName(Keys[j]).AsString; If (KeysQuotes[j] = 'YES') And (KeysType[j] <> 'String') Then Begin If CurValue_S = '' Then Begin CurString := KeysUpdate1[j]+' null '+KeysWhere2[j]; End Else Begin CurString :=KeysUpdate1[j]+'"'+CurValue_S+'"'+KeysWhere2[j]; End; End Else Begin CurString := KeysUpdate1[j]+CurValue_S+KeysWhere2[j]; End; CurStrings := CurStrings + CurString + ' '; WhereAnd := ' And '; End; U.Sql.Add('Where'); U.Sql.Add(CurStrings); U.ExecSql; U.Active := False; Except On E : Exception Do Begin Try S.Edit; S.FieldByName(ErrorField).AsString := E.Message; S.Post; Except End; End; End; S.Next; End; Try D.Active := False; D.RequestLive := True; D.DatabaseName := SourceDatabaseName; D.Sql.Clear; D.Sql.Add('Delete From '+SourceTable); D.Sql.Add('Where'); D.Sql.Add(ErrorField+' = "'+ESuccess+'"'); D.SQL.SaveToFile(FilePath+'Delete.Sql'); D.ExecSql; D.Active := False; Except If Not IsField(SourceDatabaseName, SourceTable, ErrorField) Then Begin ShowMessage('Cannot delete records from '+ SourceTable+' table because '+ErrorField+ ' Field does not exist'); End Else Begin ShowMessage('Error deleting source table records!'); End; End; Except If EMessage = ESuccess Then Begin EMessage := 'Error-Process Level- Keys:'; For K := 0 To Keys.Count -1 Do Begin EMessage := EMessage + Keys[K]+'='+S.FieldByName(Keys[K]).AsString+', '; End; End Else Begin EMessage := EMessage + 'Process Error Also'; End; Try S.Edit; S.FieldByName(ErrorField).AsString := EMessage; S.Post; Except End; End; Finally S.Free; D.SQL.SaveToFile(FilePath+'Select.Sql'); D.Free; U.SQL.SaveToFile(FilePath+'Update.Sql'); U.Free; Keys.SaveToFile(FilePath+'Keys.Txt'); Keys.Free; TimeLog.Free; CommonFields.SaveToFile(FilePath+'CommonFields.Txt'); CommonFields.Free; NonKeys.SaveToFile(FilePath+'NonKeys.Txt'); NonKeys.Free; NonKeysQuotes.SaveToFile(FilePath+'NonKeysQuotes.Txt'); NonKeysQuotes.Free; NonKeysType.SaveToFile(FilePath+'NonKeysType.Txt'); NonKeysType.Free; KeysSpaces.SaveToFile(FilePath+'KeysSpaces.Txt'); KeysSpaces.Free; KeysType.SaveToFile(FilePath+'KeysType.Txt'); KeysType.Free; KeysQuotes.SaveToFile(FilePath+'KeysQuotes.Txt'); KeysQuotes.Free; NonKeysSpaces.SaveToFile(FilePath+'NonKeysSpaces.Txt'); NonKeysSpaces.Free; NonKeysStr.SaveToFile(FilePath+'NonKeysStr.Txt'); NonKeysStr.Free; KeysWhere1.SaveToFile(FilePath+'KeysWhere1.Txt'); KeysWhere1.Free; KeysWhere2.SaveToFile(FilePath+'KeysWhere2.Txt'); KeysWhere2.Free; KeysUpdate1.SaveToFile(FilePath+'KeysUpdate1.Txt'); KeysUpdate1.Free; End; End; {!~ DeleteTable Deletes A Table} //Unit Description UnitIndex Master Index
Function DeleteTable(const DatabaseName, TableName : string):Boolean; Begin Result := DBDropTable(DatabaseName, TableName); End; {!~ DialogDBLookUp Presents a lookup Dialog to the user. The selected value is returned if the user presses OK and the Default value is returned if the user presses Cancel unless the TStringList is nil in which case a blank string is returned} //Unit Description UnitIndex Master Index
Function DialogDBLookUp( Const DataBaseName : String; Const TableName : String; Const FieldName : String; Const SessionName : String; Const DefaultValue : String; const DialogCaption : string; const InputPrompt : string; const DialogWidth : Integer ): String; Var Q : TQuery; Values : TStringlist; Begin Result := ''; Q := TQuery.Create(nil); Values := TStringlist.Create(); Try Values.Clear; Values.Sorted := True; Values.Duplicates := dupIgnore; Q.Active := False; Q.DatabaseName := DatabaseName; {$IFDEF WIN32} Q.SessionName := SessionName; {$ENDIF} Q.Sql.Clear; Q.Sql.Add('Select'); Q.Sql.Add('Distinct'); If Pos(' ',FieldName) > 0 Then Begin Q.Sql.Add('a."'+FieldName+'"'); End Else Begin Q.Sql.Add('a.'+FieldName); End; Q.Sql.Add('From'); If Pos('.DB',UpperCase(TableName)) > 0 Then Begin Q.Sql.Add('"'+TableName+'" a'); End Else Begin Q.Sql.Add(TableName+' a'); End; Q.Sql.Add('Order By'); If Pos(' ',FieldName) > 0 Then Begin Q.Sql.Add('a."'+FieldName+'"'); End Else Begin Q.Sql.Add('a.'+FieldName); End; Q.Active := True; If Not (Q.EOF And Q.BOF) Then Begin Q.First; While Not Q.EOF Do Begin Values.Add(Q.FieldByName(FieldName).AsString); Q.Next; End; Result := DialogLookupDetail( DialogCaption, InputPrompt, DefaultValue, Values, //TStringList 5, //Spacer Height 5, //Button Spacing 2, //BevelWidth 25, //PromptHeight 300, //FormHeight DialogWidth, //FormWidth 'Close dialog and return selected value.', //Hint_Cancel 'Close dialog and make no changes.', //Hint_OK 'Click an item to select it.', //Hint_ListBox True, //ListSorted False //AllowDuplicates ); End; Finally Q.Free; Values.Free; End; End; {!~ DialogLookup Presents a lookup Dialog to the user. The selected value is returned if the user presses OK and the Default value is returned if the user presses Cancel unless the TStringList is nil in which case a blank string is returned} //Unit Description UnitIndex Master Index
Function DialogLookup( const DialogCaption : string; const InputPrompt : string; const DefaultValue : string; const Values : TStringList ): string; Begin Result := LookupDialog( DialogCaption, InputPrompt, DefaultValue, Values ); End; {!~ DialogLookupDetail Presents a lookup Dialog to the user. The selected value is returned if the user presses OK and the Default value is returned if the user presses Cancel unless the TStringList is nil in which case a blank string is returned} //Unit Description UnitIndex Master Index
Function DialogLookupDetail( Const DialogCaption : string; Const InputPrompt : string; Const DefaultValue : string; Const Values : TStringList; Const ButtonSpacing : Integer; Const SpacerHeight : Integer; Const TopBevelWidth : Integer; Const PromptHeight : Integer; Const FormHeight : Integer; Const FormWidth : Integer; Const Hint_OK : string; Const Hint_Cancel : string; Const Hint_ListBox : string; Const ListSorted : Boolean; Const AllowDuplicates : Boolean ): string; Var Form : TForm; Base_Panel : TPanel; Base_Buttons : TPanel; Spacer : TPanel; Base_Top : TPanel; ButtonSlider : TPanel; ButtonSpacer : TPanel; Prompt : TPanel; ListBox : TListBox; ButtonCancelB: TPanel; ButtonOKB : TPanel; Button_Cancel: TButton; Button_OK : TButton; DefItemIndex : Integer; TempValues : TStringList; Begin Result := DefaultValue; Form := TForm.Create(Application); TempValues := TStringList.Create(); Try TempValues.Sorted := ListSorted; TempValues.Clear; If AllowDuplicates Then Begin TempValues.Duplicates := dupAccept; End Else Begin TempValues.Duplicates := dupIgnore; End; If Values <> nil Then Begin TempValues.Assign(Values); End; With Form Do Begin Try Canvas.Font := Font; BorderStyle := bsSizeable; Caption := DialogCaption; Height := FormHeight; Width := FormWidth; ShowHint := True; Position := poScreenCenter; BorderIcons := [biMaximize]; Base_Panel := TPanel.Create(Form); With Base_Panel Do Begin Parent := Form; Align := alClient; Caption := ' '; BorderWidth := 10; BorderStyle := bsNone; BevelOuter := bvNone; BevelInner := bvNone; End; Base_Buttons := TPanel.Create(Form); With Base_Buttons Do Begin Parent := Base_Panel; Align := alBottom; Caption := ' '; BorderWidth := 0; BorderStyle := bsNone; BevelOuter := bvNone; BevelInner := bvNone; Height := 27; End; ButtonSlider := TPanel.Create(Form); With ButtonSlider Do Begin Parent := Base_Buttons; Align := alClient; Caption := ' '; BorderWidth := 0; BorderStyle := bsNone; BevelOuter := bvNone; BevelInner := bvNone; End; ButtonCancelB := TPanel.Create(Form); With ButtonCancelB Do Begin Parent := ButtonSlider; Align := alRight; Caption := ' '; BorderWidth := 0; BorderStyle := bsNone; BevelOuter := bvNone; BevelInner := bvNone; Width := 75+ButtonSpacing; End; ButtonSpacer := TPanel.Create(Form); With ButtonSpacer Do Begin Parent := ButtonCancelB; Align := alLeft; Caption := ' '; BorderWidth := 0; BorderStyle := bsNone; BevelOuter := bvNone; BevelInner := bvNone; Width := ButtonSpacing; End; ButtonOKB := TPanel.Create(Form); With ButtonOKB Do Begin Parent := ButtonSlider; Align := alRight; Caption := ' '; BorderWidth := 0; BorderStyle := bsNone; BevelOuter := bvNone; BevelInner := bvNone; Width := 75; End; Spacer := TPanel.Create(Form); With Spacer Do Begin Parent := Base_Panel; Align := alBottom; Caption := ' '; BorderWidth := 0; BorderStyle := bsNone; BevelOuter := bvNone; BevelInner := bvNone; Height := SpacerHeight; End; Base_Top := TPanel.Create(Form); With Base_Top Do Begin Parent := Base_Panel; Align := alClient; Caption := ' '; BorderWidth := 10; BorderStyle := bsNone; BevelOuter := bvRaised; BevelInner := bvNone; BevelWidth := TopBevelWidth; End; Prompt := TPanel.Create(Form); With Prompt Do Begin Parent := Base_Top; Align := alTop; Caption := ' '; BorderWidth := 0; BorderStyle := bsNone; BevelOuter := bvNone; BevelInner := bvNone; Caption := InputPrompt; Height := PromptHeight; Alignment := taCenter; End; Button_Cancel := TButton.Create(Form); With Button_Cancel Do Begin Parent := ButtonCancelB; Caption := 'Cancel'; ModalResult := mrCancel; Default := True; Align := alClient; Hint := Hint_Cancel; End; Button_OK := TButton.Create(Form); With Button_OK Do Begin Parent := ButtonOKB; Caption := 'OK'; ModalResult := mrOK; Default := False; Align := alClient; Hint := Hint_OK; End; ListBox := TListBox.Create(Form); With ListBox Do Begin Parent := Base_Top; Align := alClient; Hint := Hint_ListBox; Sorted := ListSorted; Focused; If TempValues <> nil Then Begin Items.Assign(TempValues); DefItemIndex := Items.IndexOf(DefaultValue); If DefItemIndex <> -1 Then Begin ItemIndex := DefItemIndex; Selected[DefItemIndex]; End Else Begin Result := ''; ItemIndex := 0; Selected[0]; End; IntegralHeight := True; Button_OK.Default := True; Button_Cancel.Default := False; End Else Begin Result := ''; End; End; SetFocusedControl(ListBox); If ShowModal = mrOk Then Begin If ListBox.ItemIndex<>-1 Then Result := ListBox.Items[ListBox.ItemIndex]; End; Finally Form.Free; End; End; Finally TempValues.Free; End; End; {!~ DropTable Drops A Table} //Unit Description UnitIndex Master Index
Function DropTable(const DatabaseName, TableName : string):Boolean; Begin Result := DBDropTable(DatabaseName, TableName); End; {!~ EmptyTable Empties a table of all records} //Unit Description UnitIndex Master Index
Function EmptyTable( const DatabaseName, TableName : string): Boolean; Begin Result := DBEmptyTable(DatabaseName, TableName); End; {!~ ErrorMeaning Returns the meaning of the given result code. Error codes are for Delphi 1.0.} //Unit Description UnitIndex Master Index
function ErrorMeaning (ResultCode: Integer): string; const NumOfEntries = 108; type ErrorEntry = record Code: Integer; Meaning: String; end; ErrorMeaningsArray = array [1..NumOfEntries] of ErrorEntry; const MeaningsArray: ErrorMeaningsArray = {DOS errors} ((Code: 1; Meaning: 'Invalid DOS function number'), (Code: 2; Meaning: 'File not found'), (Code: 3; Meaning: 'Path not found'), (Code: 4; Meaning: 'Too many open files'), (Code: 5; Meaning: 'File access denied'), (Code: 6; Meaning: 'Invalid file handle'), (Code: 7; Meaning: 'Memory control blocks destroyed'), (Code: 8; Meaning: 'Insufficient DOS memory'), (Code: 9; Meaning: 'Invalid memory block address'), (Code: 10; Meaning: 'Invalid DOS environment'), (Code: 11; Meaning: 'Invalid format (DOS)'), (Code: 12; Meaning: 'Invalid file access code'), (Code: 13; Meaning: 'Invalid data (DOS)'), (Code: 15; Meaning: 'Invalid drive number'), (Code: 16; Meaning: 'Cannot remove current directory'), (Code: 17; Meaning: 'Cannot rename across drives'), (Code: 18; Meaning: 'No more files'), (Code: 19; Meaning: 'Disk write-protected'), (Code: 20; Meaning: 'Unknown unit (DOS)'), (Code: 21; Meaning: 'Drive not ready'), (Code: 22; Meaning: 'Unknown DOS command'), (Code: 23; Meaning: 'CRC error'), (Code: 24; Meaning: 'Bad request structure length'), (Code: 25; Meaning: 'Seek error'), (Code: 26; Meaning: 'Unknown media type'), (Code: 27; Meaning: 'Disk sector not found'), (Code: 28; Meaning: 'Out of paper'), (Code: 29; Meaning: 'Write fault'), (Code: 30; Meaning: 'Read fault'), (Code: 31; Meaning: 'General failure'), (Code: 32; Meaning: 'File sharing violation'), (Code: 33; Meaning: 'File lock violation'), (Code: 34; Meaning: 'Invalid disk change'), (Code: 35; Meaning: 'File control block unavailable'), (Code: 36; Meaning: 'Sharing buffer overflow'), (Code: 37; Meaning: 'Code page mismatch'), (Code: 38; Meaning: 'Error handling EOF'), (Code: 39; Meaning: 'Handle disk full'), (Code: 50; Meaning: 'Network request not supported'), (Code: 51; Meaning: 'Remote computer not listening'), (Code: 52; Meaning: 'Duplicate name on network'), (Code: 53; Meaning: 'Network name not found'), (Code: 54; Meaning: 'Network busy'), (Code: 55; Meaning: 'Network device no longer exists'), (Code: 56; Meaning: 'NetBIOS command limit exceeded'), (Code: 57; Meaning: 'Network adaptor error'), (Code: 58; Meaning: 'Incorrect network response'), (Code: 59; Meaning: 'Unexpected network error'), (Code: 60; Meaning: 'Incompatible remote adaptor'), (Code: 61; Meaning: 'Print queue full'), (Code: 62; Meaning: 'Not enough space for print file'), (Code: 63; Meaning: 'Print file deleted'), (Code: 64; Meaning: 'Network name deleted'), (Code: 65; Meaning: 'Access denied'), (Code: 66; Meaning: 'Network device type incorrect'), (Code: 67; Meaning: 'Network name not found'), (Code: 68; Meaning: 'Network name limit exceeded'), (Code: 69; Meaning: 'NetBIOS session limit exceeded'), (Code: 70; Meaning: 'Temporarily paused'), (Code: 71; Meaning: 'Network request not accepted'), (Code: 72; Meaning: 'Print/disk redirection paused'), (Code: 80; Meaning: 'File already exists'), (Code: 82; Meaning: 'Cannot make directory entry'), (Code: 83; Meaning: 'Fail on interrupt 24'), (Code: 84; Meaning: 'Too many redirections'), (Code: 85; Meaning: 'Duplicate redirection'), (Code: 86; Meaning: 'Invalid password'), (Code: 87; Meaning: 'Invalid parameter'), (Code: 88; Meaning: 'Network data fault'), {I/O errors} (Code: 100; Meaning: 'Disk read error'), (Code: 101; Meaning: 'Disk write error'), (Code: 102; Meaning: 'File not assigned'), (Code: 103; Meaning: 'File not open'), (Code: 104; Meaning: 'File not open for input'), (Code: 105; Meaning: 'File not open for output'), (Code: 106; Meaning: 'Invalid numeric format'), {Critical errors (Real or protected mode only)} (Code: 150; Meaning: 'Disk is write protected'), (Code: 151; Meaning: 'Unknown unit'), (Code: 152; Meaning: 'Drive not ready'), (Code: 153; Meaning: 'Unknown DOS command'), (Code: 154; Meaning: 'CRC error in data'), (Code: 155; Meaning: 'Bad drive request struct length'), (Code: 156; Meaning: 'Disk seek error'), (Code: 157; Meaning: 'Unknown media type'), (Code: 158; Meaning: 'Sector not found'), (Code: 159; Meaning: 'Printer out of paper'), (Code: 160; Meaning: 'Device write fault'), (Code: 161; Meaning: 'Device read fault'), (Code: 162; Meaning: 'Hardware failure'), {Fatal errors} (Code: 200; Meaning: 'Division by zero'), (Code: 201; Meaning: 'Range check error'), (Code: 202; Meaning: 'Stack overflow error'), (Code: 203; Meaning: 'Heap overflow error'), (Code: 204; Meaning: 'Invalid pointer operation'), (Code: 205; Meaning: 'Floating point overflow'), (Code: 206; Meaning: 'Floating point underflow'), (Code: 207; Meaning: 'Invalid floating pt. operation'), (Code: 208; Meaning: 'Overlay manager not installed'), (Code: 209; Meaning: 'Overlay file read error'), (Code: 210; Meaning: 'Object not initialised'), (Code: 211; Meaning: 'Call to abstract method'), (Code: 212; Meaning: 'Stream registration error'), (Code: 213; Meaning: 'TCollection index out of range'), (Code: 214; Meaning: 'TCollection overflow error'), (Code: 215; Meaning: 'Arithmetic overflow error'), (Code: 216; Meaning: 'General Protection Fault'), (Code: 217; Meaning: 'Unhandled exception'), (Code: 219; Meaning: 'Invalid typecast')); var Low, High, Mid, Diff: Integer; begin Low := 1; High := NumOfEntries; while Low <= High do begin Mid := (Low + High) div 2; Diff := MeaningsArray[Mid].Code - ResultCode; if Diff < 0 then Low := Mid + 1 else if Diff > 0 then High := Mid - 1 else begin {found it} Result := MeaningsArray[Mid].Meaning; Exit; end; end; {while} Result := 'Error ' + IntToStr(ResultCode) + ' (meaning unknown)'; End; {!~ FieldNo Returns the field Number as an integer. If there is an error, the table doesn't exist, the field doesn't exist or some other reason 0 is returned.} //Unit Description UnitIndex Master Index
Function FieldNo(DatabaseName, TableName, FieldName: String): Integer; Begin Result := DBFieldNo(DatabaseName, TableName, FieldName); End; {!~ FieldSize Returns the database field Size as an integer. If there is an error, the table doesn't exist, the field doesn't exist or some other reason 0 is returned.} //Unit Description UnitIndex Master Index
Function FieldSize(DatabaseName, TableName, FieldName: String): Integer; Begin Result := FieldSize(DatabaseName, TableName, FieldName); End; {!~ FieldType Returns the database field type as a string. If there is an error, the table doesn't exist, the field doesn't exist or some other reason a null string is returned.} //Unit Description UnitIndex Master Index
Function FieldType(DatabaseName, TableName, FieldName: String): String; Begin Result := TypeField(DatabaseName, TableName, FieldName); End; {!~ FieldTypeFromDataSet Returns the database field type as a string. If there is an error a null string is returned.} //Unit Description UnitIndex Master Index
Function FieldTypeFromDataSet(DataSet: TDataSet; FieldName: String): String; Begin Result := TypeFieldFromDataSet(DataSet, FieldName); End; {!~ IsEmptyDataSource Tests whether a TDataSource is empty, i.e., has no records } //Unit Description UnitIndex Master Index
Function IsEmptyDataSource(DS: TDataSource): Boolean; Var IsError : Boolean; BOF : Boolean; EOF : Boolean; ActiveWas : Boolean; Begin ActiveWas := DS.DataSet.Active; IsError := False; BOF := False; EOF := False; Try If Not DS.DataSet.Active Then DS.DataSet.Active := True; BOF := DS.DataSet.BOF; EOF := DS.DataSet.EOF; Except IsError := True End; If IsError Then Begin Result := False; End Else Begin If BOF And EOF Then Begin Result := True; End Else Begin Result := False; End; End; DS.DataSet.Active := ActiveWas; End; {!~ IsEmptyTQuery Tests whether a TQuery is empty, i.e., has no records } //Unit Description UnitIndex Master Index
Function IsEmptyTQuery(Query: TQuery): Boolean; Var IsError : Boolean; BOF : Boolean; EOF : Boolean; ActiveWas : Boolean; Begin ActiveWas := Query.Active; IsError := False; BOF := False; EOF := False; Try If Not Query.Active Then Query.Active := True; BOF := Query.BOF; EOF := Query.EOF; Except IsError := True End; If IsError Then Begin Result := False; End Else Begin If BOF And EOF Then Begin Result := True; End Else Begin Result := False; End; End; Query.Active := ActiveWas; End; {!~ IsEmptyTTable Tests whether a TTable is empty, i.e., has no records } //Unit Description UnitIndex Master Index
Function IsEmptyTTable(Table: TTable): Boolean; Var IsError : Boolean; BOF : Boolean; EOF : Boolean; ActiveWas : Boolean; Begin ActiveWas := Table.Active; IsError := False; BOF := False; EOF := False; Try If Not Table.Active Then Table.Active := True; BOF := Table.BOF; EOF := Table.EOF; Except IsError := True End; If IsError Then Begin Result := False; End Else Begin If BOF And EOF Then Begin Result := True; End Else Begin Result := False; End; End; Table.Active := ActiveWas; End; {!~ IsEmptyTable Tests whether a table is empty, i.e., has no records } //Unit Description UnitIndex Master Index
Function IsEmptyTable(DatabaseName, TableName: String): Boolean; Var Query : TQuery; IsError : Boolean; BOF : Boolean; EOF : Boolean; Begin IsError := False; BOF := False; EOF := False; Query := TQuery.Create(nil); Try Try Query.DatabaseName := DatabaseName; Query.Sql.Clear; Query.Sql.Add('Select *'); Query.Sql.Add('From'); If (Pos('.DB', UpperCase(TableName)) > 0) Or (Pos('.DBF', UpperCase(TableName)) > 0) Then Begin Query.Sql.Add('"'+TableName+'"'); End Else Begin Query.Sql.Add(TableName); End; Query.Active := True; Query.First; BOF := Query.BOF; EOF := Query.EOF; Except IsError := True End; Finally Query.Free; End; If IsError Then Begin Result := False; End Else Begin If BOF And EOF Then Begin Result := True; End Else Begin Result := False; End; End; End; {!~ IsField Returns True If DatabaseName:TableName:FieldName Exists, False Otherwise} //Unit Description UnitIndex Master Index
Function IsField(DatabaseName, TableName, FieldName: String): Boolean; Var Query : TQuery; T : TTable; i : Integer; UpperFN : String; TestFN : String; Begin Result := False; UpperFN := UpperCase(FieldName); If Not IsTable(DatabaseName, TableName) Then Exit; Query := TQuery.Create(nil); T := TTable.Create(nil); Try Try Query.DatabaseName := DatabaseName; Query.Sql.Clear; Query.Sql.Add('Select '); Query.Sql.Add('a.'+FieldName+' XYZ'); Query.Sql.Add('From'); If (Pos('.DB', UpperCase(TableName)) > 0) Or (Pos('.DBF',UpperCase(TableName)) > 0) Then Begin Query.Sql.Add('"'+TableName+'" a'); End Else Begin Query.Sql.Add(TableName+' a'); End; Query.Active := True; Result := True; Except Try T.Active := False; T.DatabaseName := DatabaseName; T.TableName := TableName; T.Active := True; If T.FieldDefs.IndexOf(FieldName) > -1 Then Begin Result := True; End Else Begin For i := 0 To T.FieldDefs.Count -1 Do Begin TestFN := UpperCase(T.FieldDefs[i].Name); If TestFN = UpperFN Then Begin Result := True; Break; End; End; End; T.Active := False; Except End; End; Finally Query.Free; T.Free; End; End; {!~ IsFieldKeyed Returns True If DatabaseName:TableName:FieldName Exists and is Keyed, False Otherwise} //Unit Description UnitIndex Master Index
Function IsFieldKeyed(DatabaseName, TableName, FieldName: String): Boolean; Var Table : TTable; FieldIndex : Integer; i : Integer; KeyCount : Integer; LocalTable : Boolean; ParadoxTbl : Boolean; DBaseTable : Boolean; TempString : String; Begin Result := False; If Not IsTable(DatabaseName, TableName) Then Exit; If Not IsField(DatabaseName, TableName, FieldName) Then Exit; TempString := UpperCase(Copy(TableName,Length(TableName)-2,3)); ParadoxTbl := (Pos('.DB',TempString) > 0); TempString := UpperCase(Copy(TableName,Length(TableName)-3,4)); DBaseTable := (Pos('.DBF',TempString) > 0); LocalTable := (ParadoxTbl Or DBaseTable); Table := TTable.Create(nil); Try Try Table.DatabaseName := DatabaseName; Table.TableName := TableName; Table.Active := True; KeyCount := Table.IndexFieldCount; FieldIndex := Table.FieldDefs.IndexOf(FieldName); If LocalTable Then Begin If ParadoxTbl Then Begin Result := (FieldIndex < KeyCount); End Else Begin Table.IndexDefs.UpDate; For i := 0 To Table.IndexDefs.Count-1 Do Begin {Need to check if FieldName is in the Expression listing} If Pos(UpperCase(FieldName),UpperCase(Table.IndexDefs[i].Expression))>0 Then Begin Result := True; Break; End; {Need to check if FieldName is in the Fields listing} If Pos(UpperCase(FieldName),UpperCase(Table.IndexDefs[i].Fields))>0 Then Begin Result := True; Break; End; End; End; End Else Begin If Table. FieldDefs[FieldIndex]. Required Then Begin Result := True; End; End; Except End; Finally Table.Free; End; End; {!~ IsRecord Returns True If The Record Exists, False Otherwise} //Unit Description UnitIndex Master Index
Function IsRecord( DatabaseName : String; TableName : String; TableKeys : TStringList; KeyValues : TStringList): Boolean; Var Q : TQuery; i : Integer; Begin Q := TQuery.Create(nil); Try Q.Active := False; Q.DatabaseName := DatabaseName; Q.RequestLive := True; Q.Sql.Clear; Q.Sql.Add('Select'); For i := 0 To TableKeys.Count - 1 Do Begin If i = (TableKeys.Count - 1) Then Begin Q.Sql.Add(TableKeys[i]); End Else Begin Q.Sql.Add(TableKeys[i]+','); End; End; Q.Sql.Add('From'); If Pos('.DB',UpperCase(TableName)) > 0 Then Begin Q.Sql.Add('"'+TableName+'" '); End Else Begin Q.Sql.Add(TableName); End; Q.Sql.Add('Where'); For i := 0 To TableKeys.Count - 1 Do Begin If i <> 0 Then Q.Sql.Add('And'); Q.Sql.Add(TableKeys[i]+' = '+ DBSqlValueQuoted(DatabaseName,TableName, TableKeys[i],KeyValues[i])); End; Q.Active := True; Result := Not IsEmptyTQuery(Q); Finally Q.Free; End; End; {!~ IsSchemaSame Returns True If The Tables Have Identical Structures, False Otherwise. If 1 Local Table is involved then Indices are ignored!!!!!!} //Unit Description UnitIndex Master Index
Function IsSchemaSame(const DatabaseName1, Table1, DatabaseName2, Table2: string): Boolean; Begin Result := IsStructureSame(DatabaseName1,Table1,DatabaseName2,Table2); End; {!~ IsStructureSame Returns True If The Tables Have Identical Structures, False Otherwise. If 1 Local Table is involved then Indices are ignored!!!!!!} //Unit Description UnitIndex Master Index
Function IsStructureSame(const DatabaseName1, Table1, DatabaseName2, Table2: string): Boolean; Var T1 : TTable; T2 : TTable; i : Integer; OneLocal : Boolean; Begin Result := False; If Not IsTable(DatabaseName1, Table1) Then Exit; If Not IsTable(DatabaseName2, Table2) Then Exit; If (Pos('.DB',UpperCase(Table1)) > 0) Or (Pos('.DB',UpperCase(Table2)) > 0) Then Begin OneLocal := True; End Else Begin OneLocal := False; End; T1 := TTable.Create(nil); T2 := TTable.Create(nil); Try Try T1.Active := False; T1.DatabaseName := DatabaseName1; T1.TableName := Table1; T1.Active := True; T2.Active := False; T2.DatabaseName := DatabaseName2; T2.TableName := Table2; T2.Active := True; If T1.FieldDefs.Count <> T2.FieldDefs.Count Then Begin Result := False; End Else Begin Result := True; For i := 0 To T1.FieldDefs.Count-1 Do Begin If (T1.FieldDefs[i].DataType <> T2.FieldDefs[i].DataType) Or (T1.FieldDefs[i].FieldClass <> T2.FieldDefs[i].FieldClass) Or (T1.FieldDefs[i].FieldNo <> T2.FieldDefs[i].FieldNo) Or (UpperCase(T1.FieldDefs[i].Name)<>UpperCase(T2.FieldDefs[i].Name)) Or (T1.FieldDefs[i].Size <> T2.FieldDefs[i].Size) Then Begin Result := False; Break; End; If (T1.FieldDefs[i].Required <> T2.FieldDefs[i].Required) And (Not OneLocal) Then Begin Result := False; Break; End; End; End; Except End; Finally T1.Free; T2.Free; End; End; {!~ IsTable Returns True If The Table Exists, False Otherwise. This procedure needs to be improved. Please give recommendations or new code.} //Unit Description UnitIndex Master Index
Function IsTable(DatabaseName, TableName: String): Boolean; Var Query: TQuery; Begin Result := False; Query := TQuery.Create(nil); Try Try Query.DatabaseName := DatabaseName; Query.Sql.Clear; Query.Sql.Add('Select *'); Query.Sql.Add('From'); If (Pos('.DB', UpperCase(TableName)) > 0) Or (Pos('.DBF',UpperCase(TableName)) > 0) Then Begin Query.Sql.Add('"'+TableName+'"'); End Else Begin Query.Sql.Add(TableName); End; Query.Active := True; Result := True; Except End; Finally Query.Free; End; End; {!~ IsTableKeyed Returns True If DatabaseName:TableName Exists and has a primary key, False Otherwise} //Unit Description UnitIndex Master Index
Function IsTableKeyed(DatabaseName, TableName: String): Boolean; Var Table : TTable; i : Integer; IsKeyed : Boolean; Begin Result := False; IsKeyed := False; If Not IsTable(DatabaseName, TableName) Then Exit; Table := TTable.Create(nil); Try Try Table.DatabaseName := DatabaseName; Table.TableName := TableName; Table.Active := True; For i := 0 To Table.FieldDefs.Count-1 Do Begin If Table.FieldDefs[i].Required Then Begin IsKeyed := True; Break; End; End; If IsKeyed Then Begin Result := True; End Else Begin Result := False; {Need to examine indexdefs} If (Pos('.DB', UpperCase(TableName)) > 0) Then Begin {Table is either Paradox or DBase} Table.IndexDefs.UpDate; If (Pos('.DBF', UpperCase(TableName)) > 0) Then Begin {Table is a DBase Table} If Table.IndexDefs.Count > 0 Then Begin Result := True; End; End Else Begin {Table is a Paradox Table} For i := 0 To Table.IndexDefs.Count-1 Do Begin If ixPrimary in Table.IndexDefs[i].Options Then Begin Result := True; Break; End; End; End; End Else Begin Result := False; End; End; Except End; Finally Table.Free; End; End; {!~ LookupDialog Presents a lookup Dialog to the user. The selected value is returned if the user presses OK and the Default value is returned if the user presses Cancel unless the TStringList is nil in which case a blank string is returned} //Unit Description UnitIndex Master Index
Function LookupDialog( const DialogCaption : string; const InputPrompt : string; const DefaultValue : string; const Values : TStringList ): string; Begin Result := DialogLookupDetail( DialogCaption, InputPrompt, DefaultValue, Values, //TStringList 5, //Spacer Height 5, //Button Spacing 2, //BevelWidth 25, //PromptHeight 300, //FormHeight 200, //FormWidth 'Close dialog and return selected value.', //Hint_Cancel 'Close dialog and make no changes.', //Hint_OK 'Click an item to select it.', //Hint_ListBox True, //ListSorted False //AllowDuplicates ); End; {!~ MoveTable Moves SourceTable From SourceDatabaseName To DestDatabasename. If a table exists with the same name at DestDatabaseName it is overwritten.} //Unit Description UnitIndex Master Index
Function MoveTable( SourceTable, SourceDatabaseName, DestDatabaseName: String): Boolean; Begin Result := DBMoveTable(SourceTable,SourceDatabaseName,DestDatabaseName); End; {!~ NFields Returns the number of fields in a table} //Unit Description UnitIndex Master Index
Function NFields(DatabaseName, TableName: String): Integer; Var Table : TTable; FieldCount : Integer; Begin Result := 0; Table := TTable.Create(nil); Try Try Table.Active := False; Table.DatabaseName := DatabaseName; Table.TableName := TableName; Table.Active := True; FieldCount := Table.FieldDefs.Count; Result := FieldCount; Except End; Finally Table.Free; End; End; {!~ SubtractTable Subtracts the records in the source table from the destination table} //Unit Description UnitIndex Master Index
Function SubtractTable( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; Begin Result := False; If (Not IsTableKeyed(DestDatabaseName,DestinationTable)) Or (Not IsTableKeyed(SourceDatabaseName,SourceTable)) Then Begin Exit; End; Result := DBRecordMove(SourceDatabaseName,SourceTable, DestDatabaseName,DestinationTable,batDelete); End; {!~ TableAdd Add source table to destination table} //Unit Description UnitIndex Master Index
Function TableAdd( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; Begin Result := AddTables(SourceDatabaseName,SourceTable, DestDatabaseName,DestinationTable); End; {!~ TableCreateFromQuery Creates a new table from a Query. Complex joins can be output to a new table.} //Unit Description UnitIndex Master Index
Function TableCreateFromQuery( Query: TQuery; NewTableName, TableDatabaseName: String): Boolean; Begin Result := DBCreateTableFromQuery(Query,NewTableName,TableDatabaseName); End; {!~ TableMove Moves SourceTable From SourceDatabaseName To DestDatabasename. If a table exists with the same name at DestDatabaseName it is overwritten.} //Unit Description UnitIndex Master Index
Function TableMove( SourceTable, SourceDatabaseName, DestDatabaseName: String): Boolean; Begin Result := DBMoveTable(SourceTable,SourceDatabaseName,DestDatabaseName); End; {!~ TableSubtract Subtracts the records in the source table from the destination table} //Unit Description UnitIndex Master Index
Function TableSubtract( const SourceDatabaseName, SourceTable, DestDatabaseName, DestinationTable: string): Boolean; Begin Result := SubtractTable(SourceDatabaseName,SourceTable, DestDatabaseName,DestinationTable); End; {!~ TypeField Returns the database field type as a string. If there is an error, the table doesn't exist, the field doesn't exist or some other reason a null string is returned.} //Unit Description UnitIndex Master Index
Function TypeField(DatabaseName, TableName, FieldName: String): String; Var Table : TTable; FieldIndex : Integer; FieldType : TFieldType; Begin Result := ''; If Not IsTable(DatabaseName, TableName) Then Exit; If Not IsField(DatabaseName, TableName, FieldName) Then Exit; Table := TTable.Create(nil); Try Try Table.Active := False; Table.DatabaseName := DatabaseName; Table.TableName := TableName; Table.Active := True; FieldIndex := Table.FieldDefs.IndexOf(FieldName); FieldType := Table.FieldDefs[FieldIndex].DataType; {TFieldType Possible Delphi 1.0 values are ftUnknown, ftString, ftSmallint, ftInteger, ftWord, ftBoolean, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime, ftBytes, ftVarBytes, ftBlob, ftMemo or ftGraphic Additional Delphi 2.0 values are: ftAutoInc ftFmtMemo ftParadoxOle ftDBaseOle ftTypedBinary } If FieldType=ftUnknown Then Result := 'Unknown'; If FieldType=ftString Then Result := 'String'; If FieldType=ftSmallInt Then Result := 'SmallInt'; If FieldType=ftInteger Then Result := 'Integer'; If FieldType=ftWord Then Result := 'Word'; If FieldType=ftBoolean Then Result := 'Boolean'; If FieldType=ftFloat Then Result := 'Float'; If FieldType=ftCurrency Then Result := 'Currency'; If FieldType=ftBCD Then Result := 'BCD'; If FieldType=ftDate Then Result := 'Date'; If FieldType=ftTime Then Result := 'Time'; If FieldType=ftDateTime Then Result := 'DateTime'; If FieldType=ftBytes Then Result := 'Bytes'; If FieldType=ftVarBytes Then Result := 'VarBytes'; If FieldType=ftBlob Then Result := 'Blob'; If FieldType=ftMemo Then Result := 'Memo'; If FieldType=ftGraphic Then Result := 'Graphic'; {$IFDEF WIN32} If FieldType=ftAutoInc Then Result := 'AutoInc'; If FieldType=ftFmtMemo Then Result := 'FmtMemo'; If FieldType=ftParadoxOle Then Result := 'ParadoxOle'; If FieldType=ftDBaseOle Then Result := 'DBaseOle'; If FieldType=ftTypedBinary Then Result := 'TypedBinary'; {$ENDIF} Except End; Finally Table.Free; End; End; {!~ TypeFieldFromDataSet Returns the database field type as a string. If there is an error a null string is returned.} //Unit Description UnitIndex Master Index
Function TypeFieldFromDataSet(DataSet: TDataSet; FieldName: String): String; Var FieldIndex : Integer; FieldType : TFieldType; Begin Try DataSet.Active := True; FieldIndex := DataSet.FieldDefs.IndexOf(FieldName); FieldType := DataSet.FieldDefs[FieldIndex].DataType; {TFieldType Possible values are ftUnknown, ftString, ftSmallint, ftInteger, ftWord, ftBoolean, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime, ftBytes, ftVarBytes, ftBlob, ftMemo or ftGraphic} If FieldType=ftUnknown Then Result := 'Unknown'; If FieldType=ftString Then Result := 'String'; If FieldType=ftSmallInt Then Result := 'SmallInt'; If FieldType=ftInteger Then Result := 'Integer'; If FieldType=ftWord Then Result := 'Word'; If FieldType=ftBoolean Then Result := 'Boolean'; If FieldType=ftFloat Then Result := 'Float'; If FieldType=ftCurrency Then Result := 'Currency'; If FieldType=ftBCD Then Result := 'BCD'; If FieldType=ftDate Then Result := 'Date'; If FieldType=ftTime Then Result := 'Time'; If FieldType=ftDateTime Then Result := 'DateTime'; If FieldType=ftBytes Then Result := 'Bytes'; If FieldType=ftVarBytes Then Result := 'VarBytes'; If FieldType=ftBlob Then Result := 'Blob'; If FieldType=ftMemo Then Result := 'Memo'; If FieldType=ftGraphic Then Result := 'Graphic'; Except End; End; End. //