📄 vafuncs.pas
字号:
//
// A helper function for the INSERT methods to check that the variant
// array passed is in the correct format
//
// Args: update_rows is the 2-dim variant array containing the row data
// num_columns is the number of columns expected
//
// Returns: TRUE on success
//
function ColumnsCheck(const rows: OleVariant; num_columns: Integer): Boolean;
var low_col, high_col, low_row, high_row: Integer;
begin
// Assume failure
Result:=FALSE;
// Correct dimensions?
if VarIsNullOrEmpty(rows) or (VarArrayDimCount(rows)<>2) then Exit;
// Get boundaries
if not GetArrayBounds(rows, high_col, low_col, high_row, low_row) then Exit;
// Correct number of rows?
if (high_row < 0) or (low_row < 0) then Exit;
// Column numbers match?
if (high_col - low_col <> num_columns - 1) then Exit;
// Success
Result:=TRUE;
end;
//
// Returns the low & high boundaries for a two-dimensional array
//
// NOTE: Assumes that the first dimension is the column and that the second
// is the row, as per standard
//
// Checks are made to ensure the variant array is an array, has 2
// dimensions, and that the bounds are valid
//
// Args: 2-dim variant array to get boundaries from
// high_col
// low_col
// high_row
// low_row
//
// Returns: TRUE on success
//
function GetArrayBounds(const var_array: OleVariant;
var high_col, low_col, high_row, low_row: Integer): Boolean;
begin
// Assume failure
Result:=FALSE;
high_col:= -1;
low_col:= -1;
high_row:= -1;
low_row:= -1;
// Check variant
if VarIsEmpty(var_array) or (VarArrayDimCount(var_array)<>2) then Exit;
// Get bounds
try
high_col:=VarArrayHighBound(var_array, 1);
low_col:=VarArrayLowBound(var_array, 1);
high_row:=VarArrayHighBound(var_array, 2);
low_row:=VarArrayLowBound(var_array, 2);
except
Exit;
end;
// Check bounds are valid
if (low_row<0) or (high_row<0) or (low_col<0) or (high_col<0) then begin
// Invalid bounds
high_col:= -1;
low_col:= -1;
high_row:= -1;
low_row:= -1;
Result:=FALSE;
end else
// Success
Result:=TRUE;
end;
//
// Returns the low boundaries for a two-dimensional array
//
// NOTE: Assumes that the first dimension is the column and that the second
// is the row, as per standard
//
// Checks are made to ensure the variant array is an array, has 2
// dimensions, and that the bounds are valid
//
// Args: 2-dim variant array to get boundaries from
// low_col
// low_row
//
// Returns: TRUE on success
//
function GetArrayLowBounds(const var_array: OleVariant;
var low_col, low_row: Integer): Boolean;
begin
// Assume failure
Result:=FALSE;
low_col:= -1;
low_row:= -1;
// Check variant
if VarIsEmpty(var_array) or (VarArrayDimCount(var_array)<>2) then Exit;
// Get bounds
try
low_col:=VarArrayLowBound(var_array, 1);
low_row:=VarArrayLowBound(var_array, 2);
except
Exit;
end;
// Check bounds are valid
if (low_row<0) or (low_col<0) then begin
// Bad bounds
low_col:= -1;
low_row:= -1;
Result:=FALSE;
end else
// Success
Result:=TRUE;
end;
//
// Copy a row, i.e. the second dimension, from the two-dimensional variant
// array src_array to the first and only dimension of the one-dimensional
// variant array dest_array.
//
// Args: src_array is the 2-dimensional array we are copying from
// dest_array is the 1-dimensional array we are copying to
// row specifies which row to copy from src_array (0=first row)
//
// NOTE: dest_array is automatically created as a 1-dimensional variant
// array with the same number of columns as the src_array. It also
// has the same low & high bounds
//
function CopyRow(const src_array: OleVariant; var dest_array: OleVariant;
const row: Integer=0): Boolean;
var high_col, low_col, high_row, low_row: Integer;
i: Integer;
begin
// Initialise
Result:=FALSE;
// Get bounds of array
if not GetArrayBounds(src_array, high_col, low_col, high_row, low_row) then Exit;
// Create destination array
dest_array:=Unassigned;
dest_array:=VarArrayCreate([low_col, high_col], varVariant);
// Copy rows to dest_arrray
for i:=0 to (high_col - low_col) - 1 do
dest_array[low_col + i]:=src_array[low_col + i, row];
// Success
Result:=TRUE;
end;
//
// Calls the other InitialiseVariantArray but sets the variant types
// to varVariant and the initial value to Unassigned. This is best used with
// database update methods.
//
// Args: variant array to clear (1-dimensional)
// number of columns in intended table, e.g. AS_USERS_COLUMNS
//
// Returns: TRUE on success
// FALSE on error
//
function InitialiseVariantArray(var var_array: OleVariant;
const columns: Integer): Boolean;
begin
Result:=InitialiseVariantArray(var_array, columns, varVariant, Unassigned);
end;
//
// This function will take a variant variable and set all the elements to
// the init_value. It will create the one-dimensional array (if required)
// and also redimension the variant to make sure it has the correct number of
// columns.
//
// It is a one-dimensional variant array containing one or more WordBool columns
// with the same number of columns as the table it is to be used with.
//
// Args: variant array to clear (1-dimensional)
// number of columns in intended table, e.g. AS_USERS_COLUMNS
// variant type, e.g. varBoolean
// initial value
//
// Returns: TRUE on success
// FALSE on error
//
function InitialiseVariantArray(var var_array: OleVariant;
const columns: Integer;
var_type: Integer;
init_value: Variant): Boolean;
var high_col, low_col: Integer;
clear_col: Integer;
begin
// Initialise
Result:=FALSE;
// Check its a valid variant array (create it if necessary)
if VarIsEmpty(var_array) then begin
var_array:=Unassigned;
var_array:=VarArrayCreate([0, columns - 1], var_type);
end;
if VarArrayDimCount(var_array)<>1 then Exit;
// Get bounds of array
low_col:=VarArrayLowBound(var_array, 1);
high_col:=VarArrayHighBound(var_array, 1);
// Add new columns?
if (high_col - low_col <> columns - 1) then
VarArrayRedim(var_array, low_col + (columns - 1));
// Clear
try
for clear_col:=low_col to high_col do
var_array[clear_col]:=init_value;
Result:=TRUE;
except
// Failed
Result:=FALSE;
end;
end;
//==============================================================================
// See the SortArray function
type
PSortRecord = ^SortRecord;
SortRecord = record
key_field: Variant;
original_row: Integer;
end;
// See the SortArray function
function SortFunction(Item1, Item2: Pointer): Integer;
var item1_rec, item2_rec: PSortRecord;
str1, str2: String;
begin
// Copy into record format
item1_rec:=item1;
item2_rec:=item2;
// What are we comparing?
case VarType(item1_rec^.key_field) of
varSmallint,
varInteger,
varSingle,
varDouble,
varCurrency,
varDate,
varByte: begin
if item1_rec^.key_field < item2_rec^.key_field then Result:= -1
else if item1_rec^.key_field > item2_rec^.key_field then Result:= 1
else Result:=0;
end;
varOleStr,
varString: begin
str1:=item1_rec^.key_field;
str2:=item2_rec^.key_field;
Result:=StrIComp(PChar(str1), PChar(str2));
end;
else
Result:=0;
end;
end;
//
// Ascendingly sorts a two-dimensional variant array
//
// Args: two-dimensional array to be sorted
//
// column to sort on (where the column is in the first dimension of
// the array)
//
// Returns: TRUE on success (var_array now sorted)
//
// Note: The column must be a string or a number
// Strings are comapared without case sensitivity
//
function SortArray(var var_array: OleVariant; sort_column: Integer): Boolean;
var sorted_row, row, sorted_column: Integer;
low_row, low_col, high_row, high_col: Integer;
key_fields: TList;
sort_row: PSortRecord;
sorted_array: OleVariant;
begin
// Get bounds of incoming array
Result:=FALSE;
if not GetArrayBounds(var_array, high_col, low_col, high_row, low_row) then Exit;
if (sort_column < low_col) or (sort_column > high_col) then Exit;
// Load the sort list
key_fields:=TList.Create;
for row:=low_row to high_row do begin
New(sort_row);
sort_row^.key_field:=var_array[low_col + sort_column, row];
sort_row^.original_row:=row;
key_fields.Add(sort_row);
end;
// Sort the list
key_fields.Sort(SortFunction);
// Copy the values into the sorted array
sorted_array:=VarArrayCreate([low_col, high_col, low_row, high_row], varVariant);
for sorted_row:=low_row to high_row do begin
// Copy the row from the original unsorted array
// to the (to be) sorted array
sort_row:=key_fields.Items[sorted_row - low_row];
for sorted_column:=low_col to high_col do
sorted_array[sorted_column, sorted_row]:=var_array[sorted_column, sort_row^.original_row];
end;
// Free memory
while key_fields.Count > 0 do begin
sort_row:=key_fields.Items[0];
key_fields.Remove(sort_row);
Dispose(sort_row);
end;
key_fields.Free;
// Done
var_array:=sorted_array;
sorted_array:=Unassigned;
Result:=TRUE;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -