Copyright: Copyright © 1998-2007 Developer Express Inc.


  TdxMemData - Getting Started

ExpressMemData is an ultra-fast in-memory TDataSet descendant you can use to bind data from any datasource (including text, binary, ini and many other file types) in conjunction with all existing VCL data-aware controls.

ExpressMemData also supports the following:

•	Sorting

•	Grouping (via the ExpressQuantumGrid)

•	Save or load to and from binary/text files

•	Multi field Locate

•	Filters

With MemData, you can create all standard field types and yes, BLOB fields are supported. You can populate MemData in two ways: As a TDataSet, by assigning values to its fields - which is easier and will be fully compatible when you decide to switch your MemData to a database back-end; Or by accessing the internal buffers of MemData as an array.

Possible uses for MemData include:

•	As a fast way to store and display data in data-aware controls. MemData also offers an easy upgrade path should you decide to move to a multi-user database at a later time.

•	As a temporary table, when processing complex reports (it is easier to populate MemData with your calculated records rather than designing complex reports).

•	As a temporary table, when doing complex editing operations - you make all the edit operations with MemData, and apply all the changes to the database at once.

•	As a local storage of remote data - you can allow your users to download tables to their local hard drive and then use MemData to browse the records, without the need for a live connection to the database.

When you use MemData in your application, no additional DLLs are required - all the functionality is built right into your program. MemData is ideal for fast, single-user applications where you require the ability to use existing data-aware control and maintain the functionality you have come to expect such as data validation.

Assume we need to create an application.  In one of its modules a user can edit (edit, delete, add) the names of Internet friends.

Data Specifications:

Object countries (Id, country name) and object Internet friends (Id, first name, last name, nickname, e-mail, birthday, interests and country).

We could use standard BDE tables, but for the sake of this example, assume we don’t want to use any database files, and of course, we don’t want to distribute our application with powerful, but very large DLLs.

In this instance, we have two options:

Use only non–data aware controls.

Use TdxMemData.

The first solution is a good one if you have lots of time or are not concerned with data validation, such as required values or correct values.  Obviously, you have to do an incredible amount of work to implement controls such as lookups, etc.

Let's now show you how easy it is to use our TdxMemData to resolve just this type of a problem.

1.	Drop two TdxMemData components onto a form.  Name the first mdCountries, the second mdIntFriends.

2.	Double click on the mdCountries component to call the MemData Field Editor screen and press the add button.  The New Field form should now be active:

To add a new field you must fill:

Field Name

Type

Size (for string fields only)

Field Type (Default data)

Lookup definition for lookup fields only

3.	Create two field ID (Integer) and Name (String, char(50)).

4.	Double click on the mdIntFriends component and add its fields:

ID (Integer), FirstName (String char(25)), LastName  (String char(25)), NickName (String char(10)), Email (String char(80)), birthday ((Date), interests (String char(250)) and CountryID (Integer).

5.	Now we have to add the lookup field to bind mdIntFreinds.CountryID < · > mdCountries.ID

Name it CountryName, type ftString, Size 50, field type – lookup and lookup definition:

Key Field – CountryID, DataSet - mdCountries, Lookup Field - ID and Result Field – Name.

Now we have a lookup field.  In both the Borland DBGrid and ExpressGrid™ by Developer Express Inc., this will be represented as a lookup combo (in the ExpressGrid, it is represented as an incremental lookup combo).

6.	Now we have to set correct ID field values for our TdxMemData components.  Write the following event handler for onAfterInsert:

procedure TForm1.dmCountriesAfterInsert(DataSet: TDataSet);

begin

  DataSet.FindField('ID').AsInteger :=

          DataSet.FindField('recid').AsInteger;

end;

You can use this code for both components: dmCountries and dmIntFriends.  ‘RECID’ is the field that is created for each TdxMemData. You can see it at design time in the Object Inspector or TdxMemData fields editor.

It is a unique, Auto Incremental field.  In this demo, we use it as an index field to get the next value for our ID fields.  It can be used as a KeyField in the dxDBGrid control.

7.	Now we have to write code to save and restore data in a text file.  Here it is:

//Loads the data on the form OnCreate event, checks if the file exists

procedure TForm1.FormCreate(Sender: TObject);

var

   FileName : String;

Begin

  FileName := ExtractFileDir(Application.ExeName) + '\countries.txt';

  If  FileExists(FileName) then

     mdCountries.LoadFromTextFile(FileName);

  FileName := ExtractFileDir(Application.ExeName) + '\intfriends.txt';

  If  FileExists(FileName) then

     mdIntFriends.LoadFromTextFile(FileName);

end;

//Saves the data on the form destroy event

procedure TForm1.FormDestroy(Sender: TObject);

begin

  mdCountries.SaveToTextFile(ExtractFileDir(Application.ExeName) + '\countries.txt');

mdIntFriends.SaveToTextFile(ExtractFileDir(Application.ExeName) + '\intfriends.txt');

end;

8.	Now drop two DataSources and name them dsCountries and dsIntFriends, then link them with your dxMemData components.

9.	Set Active to True for both TdxMemData components.  The final step is to link your DataSources with individual data controls.

And that's all you need to do!


dxMemData Unit Overview
dxMemData Unit

Classes

TdxMemData

TdxMemField

TdxMemFields

TdxMemIndex

TdxMemIndexes


TdxMemData

Hierarchy          Properties          Methods           Events

The TdxMemData is directly inherited from the TDataSet component.

Unit

dxMemData

TdxMemData = class(TDataSet);

Description

The TdxMemData works directly with memory and allows you to work with small amounts of data with lightening fast speeds.

The TdxMemData supports:

•	Calculated and lookup fields

•	Sorting by any field, including calculated and lookup fields

•	Bookmarks (multiple select for grid controls)

•	Locate, lookup methods

Note: This component does not work with Delphi™ 2 and CPP Builder™ 1.


Properties for TdxMemData
TdxMemData properties

TdxMemData               Legend

In TdxMemData

Data

DelimiterChar

FilterList

Indexes

IsLoading

ProgrammedFilter

RecIdField

ReadOnly

SortedField

SortOptions

Derived from TDataset

Active

Filter


Methods for TdxMemData
TdxMemData methods

TdxMemData

CreateFieldsFromDataSet

CreateFieldsFromStream

FillBookMarks

GetRecNoByFieldValue

GetValueCount

LoadFromDataSet

LoadFromBinaryFile

LoadFromStream

LoadFromTextFile

     Locate

MoveCurRecordTo

SaveToBinaryFile

SaveToStream

SaveToTextFile

SetFilteredRecNo

SupportedFieldType

UpdateFilters


Events for TdxMemData
TdxMemData events

TdxMemData               Legend

Derived from TDataSet

AfterCancel

AfterClose

AfterDelete

AfterEdit

AfterInsert

AfterOpen

AfterPost

AfterScroll

BeforeCancel

BeforeClose

BeforeDelete

BeforeEdit

BeforeInsert

BeforeOpen

BeforePost

BeforeScroll

OnCalcFields

OnDeleteError

OnEditError

OnFilterRecord

OnPostError


TdxMemData.Data

TdxMemData               Example

Returns the MemData's fields definitions.

property Data : TdxMemFields;

Description

Use the Data property to get access to the MemData's fields definitions.

ReadOnly Property


TdxMemData.DelimiterChar

TdxMemData          Example          See also

Determines the separator char.

property DelimiterChar : Char;

Description

Use the DelimiterChar property to determine the column separator character used by MemData when storing or restoring data within it, using the SaveToTextFile and LoadFromTextFile methods.


TdxMemData.FilterList

TdxMemData          See Also

Determines the list of filtered records.

property FilterList : TList;

Description

The FilterList property is used to maintain a list of filtered records.  If the ProgrammedFilter property is set to True, then a developer is responsible for setting the records for this list; Otherwise it is generated automatically with the help of the FilterRecord event.


TdxMemData.Indexes

TdxMemData

Determines indexes for a specific MemData control.

property Indexes: TdxMemIndexes;

Description

With ExpressMemData, a user can index data by one field similar to indexing using Paradox tables.  The Index property is used to work with these indexes via a TdxMemIndexes object.


TdxMemData.IsLoading

TdxMemData

Indicates whether the data loading process is active.

property IsLoading : Boolean;

Description

Use this property to know whether the MemData is loading data.  You can also employ this property when using your own methods of data loading.


TdxMemData.ProgrammedFilter

TdxMemData          See Also

Determines the manner in which the filtering feature is applied to the ExpressMemData.

property ProgrammedFilter : Boolean;

Description

The ProgrammedFilter property is used for faster filtering.  If this property is set to True, then the OnFilterRecord event is disabled and a developer is responsible for setting the records for the list of filtered records via the FilterList property.  If the ProgrammedFilter is set to False, then the list of filtered records is generated automatically with the help of the FilterRecord event.


TdxMemData.ReadOnly

TdxMemData

Specifies whether the MemData is read-only.

property ReadOnly : Boolean;

Description

Use the ReadOnly property to prevent users from updating, inserting, or deleting data within a MemData component.  By default, the ReadOnly property is False.


TdxMemData.RecIdField

TdxMemData

Returns a pointer to the 'recid' field of a MemData component.

property RecIdField : TField;

Description

Use the RecIdField property to return a pointer to the 'recid' field of the MemData.  'RecId' is invisible and is created automatically during the creation of a TdxMemData component.  The RecIdField is a unique field.

Note: If you do not have a unique field and wish to use the grouping capabilities of the ExpressGrid™, use this field as a KeyField property of the dxDBGrid.

Example

// Set a unique field after the insert operation.

procedure TForm1.dxMemData1AfterInsert(DataSet: TDataSet);

begin

 DataSet.FindField('id').AsInteger := DataSet.FindField('recid').AsInteger;

end;

ReadOnly Property


TdxMemData.SortedField

TdxMemData               See also

Determines the name of the field by which a MemData component is sorted.

property SortedField : String;

Description

Use the SortedColumn property to specify the field name by which the Memdata is sorted.

Note:  By default, the MemData sorts this field data in ascending order.  To change the sort order, apply the SortOptions property.  Additionally, using the SortOptions property, you can set case insensitive sorting.


TdxMemData.SortOptions

TdxMemData               See also

Specifies the sort type for a MemData component.

type

  TdxSortOption = (soDesc, soCaseInsensitive);

  TdxSortOptions = set of TdxSortOption;

property SortOptions : TdxSortOptions;

Description

Use SortOptions to specify sort type.

The following values are available:

soDesc	If active, ExpressMemData sorts in descending order, otherwise it sorts in ascending order.
soCaseInsensitive	Determines whether sorting is case insensitive.

By default, all these options are inactive.


TdxMemData.CreateFieldsFromDataSet

TdxMemData          See Also

Automatically creates fields from a specified dataset.

procedure CreateFieldsFromDataSet(DataSet : TDataSet);

Description

Call the CreateFieldsFromDataSet method to retrieve all fields from the dataset specified by the DataSet parameter.  This method checks whether a field type is supported by the ExpressMemData and then adds the supported fields.


TdxMemData.CreateFieldsFromStream

TdxMemData          See Also

Automatically creates fields from a specified stream.

procedure CreateFieldsFromStream(Stream : TStream);

Description

Call the CreateFieldsFromStream method to retrieve all fields from a stream specified by the Stream parameter.  This method checks whether a field type is supported by the ExpressMemData and then adds supported fields.

Note:  A stream must contain data in MemData internal format (For example, data written to a stream by another MemData using the SaveToStream method).


TdxMemData.FillBookMarks

TdxMemData

Fills MemData bookmarks.

procedure FillBookMarks;

Description

Call this method only when you insert data using direct access without standard DataSet methods like Append or Insert.


TdxMemData.GetRecNoByFieldValue

TdxMemData

The GetRecNoByFieldValue method returns a record number by a specifc field value.

function GetRecNoByFieldValue(Value: Variant; FieldName: String): Integer; virtual;

Description

Call the GetRecNoByFieldValue method to obtain a specific RecNo.  Use the Value and FieldName parameters to specify the required RecNo.  If an applicable record is not found, the GetRecNoByFieldValue returns -1.  If there is more than one record with a specific value, the RecNo of the first record is returned.


TdxMemData.GetValueCount

TdxMemData

Determines the number of records that contain a specified field value.

function GetValueCount(FieldName: String; Value: Variant): Integer;

Description

Call the GetValueCount method to determine how many ExpressMemData records contain the value specified by the Value parameter in the field specified by the FieldName parameter.


TdxMemData.LoadFromDataSet

TdxMemData               See also

Loads data from a specified dataset.

procedure LoadFromDataSet(DataSet: TDataSet);

Description

Call this method to load data from a dataset specified by the DataSet parameter.

Note:  When retrieving data from a dataset, make certain that this dataset contains the fields supported by ExpressMemData.


TdxMemData.LoadFromBinaryFile

TdxMemData               See also

Loads data from a binary file.

procedure LoadFromBinaryFile(FileName : String);

Description

Use this method to load data from a binary file specified by the FileName parameter.

Note: A file specified by the FileName must contain data in MemData internal format (For example, data written to a file by another MemData using the SaveToBinaryFile method).

Example

//Load data from a binary file

procedure TForm1.Button1Click (Sender: TObject);

begin

 with dxMemData1 do

  begin DisableControls;

   //Define comma as column separator

   LoadFromBinaryFile(ExtractFileDir(Application.ExeName) + 'mdata.bin');

   EnableControls;

  end;

end;


TdxMemData.LoadFromStream

TdxMemData               Example               See also

Loads data from a stream.

procedure LoadFromStream(Stream : TStream);

Description

Call LoadFromStream to populate the MemData with data from a stream.  The Stream parameter specifies the name of a stream from which to read data.

Note: A stream must contain data in MemData internal format (For example, data written to a stream by another MemData using the SaveToStream method).


TdxMemData.LoadFromTextFile

TdxMemData               Example               See also

Populates data from a text file.

procedure LoadFromTextFile(FileName : String);  dynamic;

Description

Use this method to load data from a text file specified by the FileName parameter.  By default, when loading data from a text file 'TABs' will be used as column separators.  If you have a text file with a comma as a separating character, you must set the DelimiterChar property first.

Note:  When you use the LoadFromTextFile method, you are not guaranteed that all data will be loaded properly.  If regional settings are different from original settings with which the file was created, loading errors may occur.  If you want to be certain that your file will be read properly, you have to use the SaveToBinaryFile and LoadFromBinaryFile methods.


TdxMemData.Locate

TdxMemData

Searches the KeyValues values in the KeyFields fields.

function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; override;

Description

The Locate method returns True if a record is found that matches the KeyFields and KeyValues search criteria.

The KeyFields parameter specifies record fields where the KeyValues values will be searched;

The KeyValues parameter specifies the values to be searched;

The Options parameter specifies whether the search is case sensitive and whether the partial matching is available.


TdxMemData.MoveCurRecordTo

TdxMemData               Example

Moves the current record to a new position within the MemData.

procedure MoveCurRecordTo(Index : Integer);

Description

Use this method if you wish to move the current active record to another position specified by the Index parameter.  Note that you should pass 1 to move the record to the first position.  Passing zero or negative values has no effect.


TdxMemData.SaveToBinaryFile

TdxMemData               See also

Saves data to a binary file.

procedure SaveToBinaryFile(FileName : String);

Description

Use this method if you want to save data to a binary file, specified by the FileName parameter.

Example

//Saves data to a binary file

procedure TForm1.Button1Click(Sender: TObject);

begin

  dxMemData1.SaveToBinaryFile(ExtractFileDir(Application.ExeName) + 'mdata.bin');

end;


TdxMemData.SaveToStream

TdxMemData               Example               See also

Saves data to a stream.

procedure SaveToStream(Stream : TStream);

Description

Call the SaveToStream method to write the MemData's data to a stream.  The Stream parameter specifies the name of the existing stream.


TdxMemData.SaveToTextFile

TdxMemData               Example               See also

Saves data to a text file.

Procedure SaveToTextFile(FileName : String); dynamic;

Description

Use this method if you wish to save data to a text file, specified by the FileName parameter.  By default, when saving data to a text file, 'TAB's will be used as column separators.  If you want to use a different column separator, you have to use the DelimiterChar property.

Note: When you use the SaveToTextFile method, you are not guaranteed that all data will be loaded properly at a future point in time.  If regional settings differ from original settings, with which the file was created, loading errors may occur.  To be certain that your file will be read properly regardless of regional settings, you have to use the SaveToBinaryFile and LoadFromBinaryFile methods.


TdxMemData.SetFilteredRecNo

TdxMemData

Sets the active filtered record.

procedure SetFilteredRecNo(Value: Integer);

Description

Call the SetFilteredRecNo method to activate a record whose index, in the list of filtered records, is equal to the Value property.


TdxMemData.SupportedFieldType

TdxMemData

Determines whether a specific FieldType is supported by the TdxMemData.

function SupportedFieldType(AType: TFieldType): Boolean;  virtual;

Description

Use the SupportedFieldType to determinate whether a field type is supported by the MemData (As determined by the AType parameter).  If a given field type is supported, the SupportedFieldType returns True; Otherwise - False.

Note: With the release of v1.4, BLOB fields are supported.


TdxMemData.UpdateFilters

TdxMemData

Updates MemData filters.

procedure UpdateFilters; virtual;

Description

Call this method to update the MemData filters which can be defined in the OnFilterRecord event.  Use this method when making changes to filter definitions.


TdxMemField

Hierarchy          Properties          Methods          See also

The TdxMemField is the object used by a MemData component to store specific memory field definitions.

Unit

dxMemData

TdxMemField = class(TCollectionItem);

Description

The TdxMemField object allows you to get access to the memory field definition.  Each of MemData's memory fields is a list of pointers to field values.


Properties for TdxMemField
TdxMemField properties

TdxMemField               Legend

DataSet

Field

HasValues

Index

 	MemFields

Values


Methods for TdxMemField
TdxMemField methods

TdxMemField               Legend

AddValue

InsertValue


TdxMemField.DataSet

TdxMemField

Specifies a corresponding dataset.

property DataSet : TdxMemData;

Description

Use this property to get access to a corresponding MemData component.

This is a ReadOnly property.


TdxMemField.Field

TdxMemField

Specifies a corresponding field.

property Field : TField;

Description

Use this property to get access to a corresponding field definition.

This is a ReadOnly property.


TdxMemField.HasValues

TdxMemField

property HasValues[Index:Integer]: Char;

Description

This property is used internally by the SaveToStream and Locate methods.  You might never need to use it directly.


TdxMemField.Index

TdxMemField          See Also

Specifies the field definition’s index number in the Fields property of a dataset.

property Index: Integer;

Description

Use the Index property to locate a field within a dataset.  Change the value of the Index property to change the location of a field within a dataset.  Changing the Index value affects the order in which fields are displayed in data grids, but not their position in the physical database tables.

Note:  The field order can also be changed by dragging and dropping fields in the Fields editor at design time.


TdxMemField.MemFields

TdxMemField

Determines the corresponding TdxMemFields object.

property MemFields : TdxMemFields;

Description

Use the MemFields property to get access to a TdxMemFields object, which contains the MemField.

ReadOnly Property


TdxMemField.Values

TdxMemField               Example               See also

Determines the values of a MemField.

property Values[Index: Integer]: PChar;

Description

Use the Values property to read values stored within the field.  The value is read from the record whose index is specified by the Index parameter.  Note that record indexes are zero-based.  Passing a negative value or a value exceeding the last available index raises an exception.

ReadOnly property


TdxMemField.AddValue

TdxMemField          See Also

Adds a new field definition to a TdxMemField object instance.

procedure AddValue(const Buffer : PChar);

Description

Call the AddValue method to add a new field definition to the end of the list of available field definitions for a specific field.  The Buffer parameter determines the value to add.  When added, the new value can be displayed.


TdxMemField.InsertValue

TdxMemField          See Also

Inserts a new field definition to a TdxMemField object instance.

procedure InsertValue(AIndex : Integer; const Buffer : PChar);

Description

Call the InsertValue method to insert a new field definition to the list of available field definitions of a specific field.  The AIndex parameter determines the position at which a new value is inserted.  The Buffer parameter determines the value to add.  When added a new value can be displayed.


TdxMemFields

Hierarchy               Properties               Methods

TdxMemFields is a collection of TdxMemField objects used by a MemData component to store the memory fields definitions.

Unit

dxMemData

TdxMemFields = class(TCollection);

Description

TdxMemFields is a container for MemData's memory fields.  It is a collection of lists, where each item is a TdxMemField object.


Properties for TdxMemFields
TdxMemFields properties

TdxMemFields               Legend

Count

DataSet

Items

RecordCount


Methods for TdxMemFields
TdxMemFields methods

TdxMemFields               Legend

Add

AddField

Clear

DeleteRecord

GetCount

IndexOf

InsertRecord

RemoveField


TdxMemFields.Count

TdxMemFields          See Also

Indicates the number of memory fields in a TdxMemFields collection.

property Count : Integer;

Description

Use the Count property to obtain the number of memory fields.

ReadOnly Property


TdxMemFields.DataSet

TdxMemFields

Specifies a corresponding dataset.

property DataSet : TdxMemData;

Description

Use this property to get access to a corresponding MemData component.

ReadOnly Property


TdxMemFields.Items

TdxMemFields               Example

Lists the MemField definitions that describe each memory field in a MemData component.

property Items[Index:Integer] : TdxMemField;

Description

To access a specific MemField's definition specify the Index parameter.  The Index parameter is in the range from 0 to Count - 1.

This is a ReadOnly property.


TdxMemFields.RecordCount

TdxMemFields          See Also           Example

Indicates the total number of records in a corresponding MemData.

property RecordCount : Integer;

Description

The RecordCount property returns the total number of records in a corresponding MemData.

ReadOnly Property


TdxMemFields.Add

TdxMemFields          See Also

Adds a new field to the memory fields collection.

function Add(AField : TField) : TdxMemField;

Description

Call the Add method to add a new memory field specified by the AField parameter to the end of the available fields list.  This method returns the newly created TdxMemField object.


TdxMemFields.AddField

TdxMemFields          See Also

Adds a new field to the memory fields collection.

procedure AddField(Field : TField);

Description

The AddField method is used internally to add a new memory field specified by the AField parameter.  If this field is not in the list of available fields, it is added to the end of the list.


TdxMemFields.Clear

TdxMemFields          See Also

Deletes all memory fields from the TdxMemFields collection.

procedure Clear;

Description

The Clear method frees the memory used to store the memory fields list and all corresponding records.


TdxMemFields.DeleteRecord

TdxMemFields          See Also

Deletes a specific record.

procedure DeleteRecord(AIndex : Integer);

Description

Call the DeleteRecord method to delete a record specified by the AIndex parameter.  The first record has an index of 0, the second record has an index of 1, etc.  The last record has an index of Count-1.


TdxMemFields.GetCount

TdxMemFields          See Also

Returns the number of memory fields in a TdxMemFields collection.

function GetCount : Integer;

Description

The GetCount method is used internally to obtain the number of memory fields.


TdxMemFields.IndexOf

TdxMemFields

Locates the MemField object in a MemFields array.

Function IndexOf(Field : TField): TdxMemField;

Description

Call the IndexOf to get the MemField specified by the Field parameter.  If the required field is not found, IndexOf returns nil.


TdxMemFields.InsertRecord

TdxMemFields          See Also

Inserts a new record.

procedure InsertRecord(Buffer: Pointer; AIndex : Integer; Append: Boolean);

Description

Call the InsertRecord method to insert a new record into the ExpressMemData.  The Buffer parameter contains a pointer to the inserted record.  AIndex determines the index at which to insert this record.  The first record has an index of 0, the second record has an index of 1 etc.  The last record has an index of Count-1.  The Append parameter determines whether to add or insert a new record.  If this parameter is True, then a record is simply added to the end of all records; If False, it is inserted at the specified position and indexes of all subsequent records are recalculated.


TdxMemFields.RemoveField

TdxMemFields          See Also

Removes a field from the memory fields collection.

procedure RemoveField(Field : TField);

Description

Call the RemoveField method to delete a field specified by the Field parameter from the list of available memory fields in the TdxMemFields collection.


TdxMemData Hierarchy
    Hierarchy

TObject

     |

TPersistent

     |

TComponent

     |

TDataSet

     |


Scope

Protected

Published

Accessibility

ReadOnly


TdxMemField Hierarchy
   Hierarchy

TObject

     |

TPersistent

     |

TCollectionItem

     |


TdxMemFields Hierarchy
   Hierarchy

TObject

     |

TPersistent

     |

TCollection

     |


TdxMemFieldRec Hierarchy
   Hierarchy

TObject

     |


TdxMemData.MoveCurRecordTo,example
TdxMemData.MoveCurRecordTo example

This example demonstrates how to move a specific record.

//Moves a specified record to the beginning of the MemData

procedure TForm1.Button3Click(Sender: TObject);

begin

  dxMemData1.DisableControls;

  //Move record

  dxMemData1.MoveCurRecordTo(1);

  dxMemData1.EnableControls;

  //Go to the first record

  dxMemData1.First;

end;


SaveToStream, LoadFromStream example
TdxMemData.SaveToStream, TdxMemData.LoadFromStream example

This example demonstrates how to save and load a MemData instance using a stream.

//Copies data from one MemData component to another

procedure TForm1.Button1Click(Sender: TObject);

var

  fMem : TMemoryStream;

begin

 fMem := TMemoryStream.Create;

 //Saves the 1st MemData data to a stream

 dxMemData1.SaveToStream(fMem);

 //Sets the Stream position

 fMem.Position := 0;

 //Populates the 2nd MemData data from the stream, containing data from the 1st MemData

 dxMemData2.LoadFromStream(fMem);

 fMem.Free;

end;


DelimiterChar, SaveToTextFile, LoadFromTextFile example
TdxMemData.DelimiterChar, TdxMemData.SaveToTextFile, TdxMemData.LoadFromTextFile  example

This example demonstrates how to save and load a MemData instance using a text file.

//Saves data to a text file with commas as column separators

procedure TForm1.Button1Click(Sender: TObject);

begin

  //Defines commas as column separators

  dxMemData1.DelimiterChar := ',';

  dxMemData1.SaveToTextFile(ExtractFileDir(Application.ExeName) + 'mdata.txt');

end;

//Loads data from a text file with commas as column separators

procedure TForm1.Button2Click (Sender: TObject);

begin

  with dxMemData1 do begin

    DisableControls;

    DelimiterChar := ',';

    //Define comma as column separator

    LoadFromTextFile(ExtractFileDir(Application.ExeName) + 'mdata.txt');

    EnableControls;

  end;

end;


Direct Access example

This examples demonstrates how to obtain access to each value of a MemData component.

procedure TForm1.Button1Click(Sender: TObject);

var

  i, j : Integer;

  s : string;

begin

  with dxMemData do

    for i := 0 to RecordCount - 1 do begin

      s := '';

      for j := 0 to Fields.Count - 1 do begin

        if j = 0 then //determines the RecId field

          Continue;

          if s <> '' then

            s := s + ' ' + dxMemData.Data.Items[j].Values[i]

          else

            s := dxMemData.Data.Items[j].Values[i];

      end;

      Memo.Lines.Add(s);

    end;

end;


TdxMemIndex

Hierarchy          Properties          Methods

TdxMemIndex is the object used by a MemData component to store a specific index for a memory field.

Unit

dxMemData

TdxMemField = class(TCollectionItem);

Description

With ExpressMemData, a user can index data by one field similar to indexing applied to Paradox tables.   The TdxMemIndex object allows you to work with a single index.


TdxMemIndex Hierarchy
Hierarchy

TObject

     |

TPersistent

     |

TCollectionItem

     |


Properties for TdxMemIndex
TdxMemIndex properties

TdxMemIndex               Legend

FieldName


Methods for TdxMemIndex
TdxMemIndex methods

TdxMemIndex               Legend

GetMemData

GotoNearest

Prepare


TdxMemIndex.FieldName

TdxMemIndex

Determines the field name to be indexed.

property FieldName: String;

Description

Use the FieldName property to specify the index for ExpressMemData.  If this property contains a valid field name, then that index determines the sort order of records.

Note: Only one field name can be specified in each index.


TdxMemIndex.GetMemData

TdxMemIndex

Determines a MemData instance.

function GetMemData: TdxMemData;

Description

The GetMemData method returns a specific MemData instance to which the current index is applied.


TdxMemIndex.GotoNearest

TdxMemIndex

Locates a record with a specific value in ExpressMemData.

function GotoNearest(const Buffer : PChar; var Index : Integer) : Boolean;

Description

The GotoNearest method is called to locate a record that contains the value specified by the Buffer parameter in the current MemData instance.  The Index parameter determines the index of the resultant record.  This method returns True if the search was successful; Otherwise False.


TdxMemIndex.Prepare

TdxMemIndex

Prepares a MemData instance to use the current index.

procedure Prepare;

Description

Since ExpressMemData allows you to create several indexes, this method rebuilds a MemData instance to apply the new index.


TdxMemIndexes

Hierarchy          Methods

TdxMemIndexes is a collection of TdxMemIndex objects used by a MemData component to maintain indexes for memory field definitions.

Unit

dxMemData

TdxMemIndexes = class(TCollection);

Description

With ExpressMemData, a user can index data by one field similar to indexing applied to Paradox tables.  The TdxMemIndexes object maintains a list of these indexes.  Each item of this list represents an independent index against which a sort order can be based.


TdxMemIndexes Hierarchy
Hierarchy

TObject

     |

TPersistent

     |

TCollection

     |


Methods for TdxMemIndexes
TdxMemIndexes methods

TdxMemIndexes               Legend

Add

GetIndexByField


TdxMemIndexes.Add

TdxMemIndexes

Adds a new index to the collection of available indexes.

function Add: TdxMemIndex;

Description

Call the Add method to create a new item in the collection of indexes in the ExpressMemData.


TdxMemIndexes.GetIndexByField

TdxMemIndexes

Returns a specific TdxMemIndex instance.

function GetIndexByField(AField: TField): TdxMemIndex;

Description

Since each memory field can contain only a single index, the GetIndexByField method allows you to locate a specific index that corresponds to the field specified by the AField parameter.


How to Populate a MemData Table from Another MemData or Any Other TDataSet Descendant

This article demonstrates how to populate a MemData table, with another MemData or any other TDataSet descendant.  To accomplish this, you should use the LoadFromDataSet method. Here is the code:

// Delphi code
dxMemData1.Close;
dxMemData1.LoadFromDataSet(dxMemData2);

// C++Builder code
dxMemData1->Close();
dxMemData1->LoadFromDataSet(dxMemData2);


How to Add Different Types of Data to MemData

This article illustrates the quickest way to populate MemData fields. You can perform this by directly accessing MemData data.  For instance, to add new data to a field with #0, you should make use of the mData.Data.Items[0].AddValue string.

Additionally, to add different types of data, you should use the VariantToMemDataValue global procedure declared in the dxmdaset unit, which converts your data so that it’s compatible with the MemData memory field data.

// Delphi code

procedure TForm1.Button1Click(Sender: TObject);

var

  I: Integer;

  P: Pointer;

begin

// MemData must be active

mData.Active := True;

// Disable the data controls to prevent the flickers

mData.DisableControls;

GetMem(P, 255);

try

for I := 1 to 10 do

begin

mData.Data.Items[0].AddValue(@i);

// string

VariantToMemDataValue('Number ' + IntToStr(I), P, mDataString);

mData.Data.Items[1].AddValue(P);
// Integer
mData.Data.Items[2].AddValue(@I);
// Boolean
VariantToMemDataValue((I mod 2) = 0, P, mDataBoolean);
mData.Data.Items[3].AddValue(P);
// Float
VariantToMemDataValue(1 / I, P, mDataFloat);
mData.Data.Items[4].AddValue(P);
// Date
VariantToMemDataValue(Now + I, P, mDataDate);
mData.Data.Items[5].AddValue(P);
// Date and time
VariantToMemDataValue(Now + 1 / I, P, mDataDateTime);
mData.Data.Items[6].AddValue(P);
end;
mData.FillBookmarks;
mData.First;
finally
FreeMem(P);
// Enabled the data controls
mData.EnableControls;
end;
end;

// C++Builder code
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// MemData must be active
mData->Active = true;
// Disable the data controls to prevent the flickers
mData->DisableControls();

char* P = new char [255];
try
{
for (int i = 1; i <= 10; i++)
{
mData->Data->Items[0]->AddValue((char *)&i);
// string
VariantToMemDataValue("Number " + IntToStr(i), P, mDataString);
mData->Data->Items[1]->AddValue(P);
// Integer
mData->Data->Items[2]->AddValue((char *)&i);
// Boolean
VariantToMemDataValue(i % 2 == 0, P, mDataBoolean);
mData->Data->Items[3]->AddValue(P);
// Float
VariantToMemDataValue((float)1 / (float)i, P, mDataFloat);
mData->Data->Items[4]->AddValue(P);
// Date
VariantToMemDataValue((int)Now() + i, P, mDataDate);
mData->Data->Items[5]->AddValue(P);
// Date and time
VariantToMemDataValue((double)Now() + (float)1 / (float)i, P, mDataDateTime);
mData->Data->Items[6]->AddValue(P);
}
mData->FillBookMarks();

mData->First();
}
__finally
{
delete [] P;
// Enabled the data controls
mData->EnableControls();
}
}
//------------------------------------------------------------------


How to Populate MemData via Direct Memory Access

This example demonstrates how to append a new record that contains two fields (an integer and a string) to a MemData component.  Remember to call the FillBookmarks and Last methods.

// Delphi code
var
i: Integer;
...
i := 99999;
// Determines RecId field
dxMemData1.Data.Items[0].AddValue(@i);
// Determines integer field
dxMemData1.Data.Items[1].AddValue(@i);
// Determines string field
dxMemData1.Data.Items[2].AddValue(PChar('New value'));
dxMemData1.FillBookMarks;
dxMemData1.Last;

// C++Builder code
int i = 99999;
// Determines RecId field
dxMemData1->Data->Items[0]->AddValue((char *)&i);
// Determines integer field
dxMemData1->Data->Items[1]->AddValue((char *)&i);
// Determines string field
dxMemData1->Data->Items[2]->AddValue(PChar("New value"));
dxMemData1->FillBookMarks();
dxMemData1->Last();