我正在尝试使用 Lazarus 和 SQLdb 组件编写一个简单的 SQLite 3 应用程序。
我已设法连接到数据库并填充TDBGrid
. 问题是所有作为文本字段的列都显示值“(MEMO)”而不是数据库中的字符串。
我找到了一个简单的解决方案:
必须启用该属性dgDisplayMemoText
。DBGrid
我忘记了它的来源,但这就是我对 tdbgrid 中的备忘录字段所做的事情。关于 gettext 事件,蓝色是正确的,这是在代码中实现它的方法:
创建一个名为 MemoDifier 的类:
MemoDifier = class
public
procedure DBGridOnGetText(Sender: TField; var aText: string;
DisplayText: boolean);
end;
在代码的实现部分,输入:
procedure MemoDifier.DBGridOnGetText(Sender: TField; var aText: string;
DisplayText: boolean);
begin
if (DisplayText) then
aText := Sender.AsString;
end;
然后单击表单中的 tdbgrid 控件,然后在Object Inspector (Lazarus IDE) 中单击 Events 选项卡,滚动到下方以找到 OnPrepareCanvas 事件。双击它以生成代码。然后修改代码以满足您的需要,例如您的 tdbgrid 控件的名称:
procedure Tmainui.TDBGrid1PrepareCanvas(sender: TObject;
DataCol: Integer; Column: TColumn; AState: TGridDrawState);
var
MemoFieldReveal: MemoDifier;
begin
if (DataCol = 1) then
begin
try
TDBGrid1.Columns.Items[0].Field.OnGetText := @MemoFieldReveal.DBGridOnGetText;
TDBGrid1.Columns.Items[1].Field.OnGetText := @MemoFieldReveal.DBGridOnGetText;
TDBGrid1.Columns.Items[2].Field.OnGetText := @MemoFieldReveal.DBGridOnGetText;
except
On E: Exception do
begin
ShowMessage('Exception caught : ' + E.Message);
end;
end;
end;
end;
变量 MemoFieldReveal 指向类 MemoDifier。不要忘记修改索引 (Items[x]) 以指向显示 (MEMO) 文本的 tdbgrid 项目/字段的索引号。
另外的选择
如果您使用的是 TZConection,请在连接数据库时将此行添加到您的代码中
TZConnection).Properties.Add('Undefined_Varchar_AsString_Length=100');
备注字段不能显示在TDBGrid
. 添加TDBMemo
到表单并将其连接到相同的TDataSource
. 在这种情况下,您将在备忘录中看到文本。
正如 IRC 上所说,您可能需要将查询的字段添加到表单中(以便为它们生成“字段”组件),然后实现TMemoField.GetText
事件。
查看在对象检查器中输入“字段”字段是否会打开一个编辑器来生成组件(它在 Zeos iirc 中这样做)。
一个明显简单的解决方案是在列类型中使用类似 VARCHAR(n) 的东西来限制字段中 TEXT 的长度,其中 n 是允许的最大字符数。
老问题,但我在寻找类似问题时遇到了它,但在通过代码而不是 DBGrid 检索的数据上;当我使用方法DisplayText
或检索字符串字段时Text
,我得到了“(备忘录)”而不是正确的值。
答案其实很简单…… TSQLQuery 类拥有一组方法AsXxx
,根据数据类型调用这些方法来获取数据。这里使用 AsString 来内联分配一个变量。
SQLQuery1.Open;
//some check to make sure there are fields
name:=SQLQuery1.Fields[1].AsString; //gives "English" for example
code:=SQLQuery1.Fields[2].DisplayText; //gives "(Memo) instead of "en"
此外,如果您在设计时不知道该变量是哪种类型(例如,您想为任何类型的表设计一个通用函数),那么您的 TSqlQuery 对象的 FieldDefs 属性可以帮助您。它拥有一个允许选择使用哪个 AsXxx 函数的 DataType 属性。以这里为例。
SQLQuery1.Open;
//some check to make sure there are fields
with SQLQuery1.FieldDefs[1].DataType of
ftMemo: SQLQuery1.Fields[1].DisplayText; //gives "(Memo)"
ftString: name:=SQLQuery1.Fields[1].AsString; //gives "English" for example
...
end;
如果您在调试时查看数据类型,您会注意到使用 SQLite,任何文本都被视为 ftMemo,而不是 ftString,因为那里只有一种文本类型。
我在 MySQL 和 Tgrid 中也有同样的情况,所以我希望答案是一样的,因为它很简单:-)
说如果 s 是导致问题的字段,那么而不是写
SELECT s
写
SELECT LEFT(s,200) AS s
本文给出了一个解决方案:在 Delphi 的 TDBGrid 中显示和编辑 MEMO 字段。
在这里,我总结了您必须做的事情:
OnGetText = MyDataSetMyFieldGetText
到属于您的数据集的(TMemoField
这里命名MyField
)(例如 a TTable
,这里命名MyDataSet
)在表单定义中的 .pas > interface
> type
> 中,添加
procedure MyDataSetMyFieldGetText(Sender: TField; var Text: string; DisplayText: Boolean);
在 .pas >>implementation
添加这个方法
procedure TDM.WorkVisiteNoteGetText(Sender: TField; var Text: string; DisplayText: Boolean);
begin
Text := Copy(WorkVisiteNote.AsString, 1, 100);
end;