【发布时间】:2011-01-26 19:52:38
【问题描述】:
我正在尝试使用 Lazarus 和 SQLdb 组件编写一个简单的 SQLite 3 应用程序。
我已成功连接到数据库并填充了TDBGrid。问题是所有作为文本字段的列都显示值“(MEMO)”而不是数据库中的字符串。
【问题讨论】:
-
更改数据库中的列类型可解决此问题,请参阅my answer
标签: delphi sqlite lazarus memo
我正在尝试使用 Lazarus 和 SQLdb 组件编写一个简单的 SQLite 3 应用程序。
我已成功连接到数据库并填充了TDBGrid。问题是所有作为文本字段的列都显示值“(MEMO)”而不是数据库中的字符串。
【问题讨论】:
标签: delphi sqlite lazarus memo
我找到了一个简单的解决方案:
必须启用来自DBGrid 的属性dgDisplayMemoText。
【讨论】:
我忘记了它的来源,但这就是我对 tdbgrid 中的备注字段所做的事情。 bluish 对 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) 中单击“事件”选项卡,向下滚动以找到 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');
【讨论】:
正如 IRC 上所说,您可能需要将查询的字段添加到表单中(以便为它们生成“字段”组件),然后实现 TMemoField.GetText 事件。
查看在对象检查器中输入“字段”字段是否会打开一个编辑器来生成组件(它在 Zeos iirc 中这样做)。
【讨论】:
备注字段不能在TDBGrid 中显示。将TDBMemo 添加到表单并将其连接到相同的TDataSource。在这种情况下,您将在备忘录中看到文本。
【讨论】:
我在 MySQL 和 Tgrid 中也有同样的情况,所以我希望答案是一样的,因为它很简单 :-)
说如果 s 是导致问题的字段 then 而不是写
SELECT s
写
SELECT LEFT(s,200) AS s
【讨论】:
一个明显简单的解决方案是在列类型中使用类似 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,因为那里只有一种文本类型。
【讨论】:
本文给出解决方案:Displaying and editing MEMO fiels in Delphi's TDBGrid。
这里我总结一下你要做的事情:
OnGetText = MyDataSetMyFieldGetText 添加到属于您的数据集的TMemoField(此处命名为MyField)(例如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;
【讨论】: