If you are developing database applications with tables containing MEMO fields, you'll notice that, by default, the TDBGrid component does not show the contents of a MEMO field inside a DBGrid cell.
Memo fields are used to represent lengthy text or combinations of text and numbers. When building database applications using Delphi, the TMemoField object is used to represent a memo field in a dataset. TMemoField encapsulates the fundamental behavior common to fields that contain text data or arbitrary length. In most databases, the size of the Memo field is limited by the size of the database.
While you can display the contents of a MEMO field in a TDBMemo component, by design the TDBGrid will only display "(Memo)" for the contents of such fields.
In order to actually display some text (from the MEMO field) in the appropriate DBGrid cell, you'll only need to add a simple line of code…
For the purpose of the next discussion, let's say you have a database table named "TestTable" with at least one MEMO field named "Data".
To show the contents of a MEMO field in the DBGrid, you need to attach a simple line of code in the field's OnGetText event. The easiest way to create the OnGetText event handler is to use the Fields editor at design time to create a persistent field component for the memo field:
- Connect your TDataset descendant component (TTable, TQuery, TADOTable, TADOQuery… ) to the "TestTable" database table.
- Double click the dataset component to open the Fields editor
- Add the MEMO field to the list of persistent fields
- Select the MEMO field in the Fields editor
- Activate the Events tab in the Object Inspector
- Double click the OnGetText event to create the event handler
Add the next line of code (italicized below):
procedure TForm1.DBTableDataGetText( Sender: TField; var Text: String; DisplayText: Boolean); begin Text := Copy(DBTableData.AsString, 1, 50);
Note: the dataset object is called "DBTable", the MEMO field is called "DATA", and therefore, by default, the TMemoField connected to the MEMO database field is called "DBTableData". By assigning DBTableData.AsString to the Text parameter of the OnGetText event, we tell Delphi to display ALL the text from the MEMO field in a DBGrid cell.
You can also adapt the DisplayWidth of the memo field to a more appropriate value.
Note: since MEMO fields can be quite BIG, it is a good idea to show only a part of it. In the above code, only the first 50 characters are displayed.
Editing on a separate form
By default, the TDBGrid does not allow editing of MEMO fields. If you want to enable "in place" editing, you could add some code to react on a user action that shows a separate window that allows editing using a TMemo component.
For the sake of simplicity we'll open an editing window when ENTER is pressed "on" a MEMO field in a DBGrid.
Let's use the KeyDown event of a DBGrid component:
procedure TForm1.DBGrid1KeyDown( Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_RETURN then begin if DBGrid1.SelectedField = DBTableData then with TMemoEditorForm.Create(nil) do try DBMemoEditor.Text := DBTableData.AsString; ShowModal; DBTable.Edit; DBTableData.AsString := DBMemoEditor.Text; finally Free; end; end; end;
Note 1: the "TMemoEditorForm" is a secondary form containing only one component: "DBMemoEditor" (TMemo).
Note 2: the "TMemoEditorForm" was removed from the "Auto-create forms" list in the Project Options dialog window.
Let's see what happens in the DBGrid1's KeyDown event handler:
- When a user presses the ENTER key (we are comparing the Key parameter to the VK_RETURN virtual key code) Key = VK_RETURN,
- If the currently selected field in the DBGrid is our MEMO field (DBGrid1.SelectedField = DBTableData),
- We create the TMemoEditorForm TMemoEditorForm.Create(nil),
- Send the value of the MEMO field to the TMemo component DBMemoEditor.Text := DBTableData.AsString,
- Display the form modally ShowModal,
- When a user finishes with editing and closes the form, we need to put the dataste into the Edit mode DBTable.Edit,
- In order to be able to assign the edited value back to our MEMO field DBTableData.AsString := DBMemoEditor.Text.
Note: if you are looking for more TDBGrid related articles and usage tips, be sure to visit: "TDBGrid to the MAX" tips collection.