DBGrid显示字符串字段的值为“(MEMO)”

9
我正在尝试使用Lazarus和SQLdb组件编写一个简单的SQLite应用程序。
我连接到数据库并填充了一个TDBGrid。问题是,所有文本字段显示值“(MEMO)”,而不是数据库中的字符串。

在数据库中更改列类型可以解决此问题,请参见我的回答 - Wolf
12个回答

5
我找到了一个简单的解决方案:
必须启用来自DBGriddgDisplayMemoText属性。

2

我不知道这篇文章的来源,但是我正在使用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控件,在对象检查器(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])修改为您的tdbgrid项/字段的索引号,该项/字段显示(MEMO)文本。

1

虽然这是一个老问题,但我在寻找类似问题的解决方案时遇到了它,不同的是我是通过代码检索数据而不是使用DBGrid。当我使用DisplayTextText方法检索字符串字段时,我得到的是“(memo)”而不是正确的值。

答案其实很简单... 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属性来帮助您。它拥有一个DataType属性,允许选择要使用哪个AsXxx函数。以下是一个示例。
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,因为那里只有一种文本类型。


1

TDBGrid 中无法显示备忘字段。在表单中添加 TDBMemo 并将其连接到相同的 TDataSource。在这种情况下,您将在备忘录中看到文本。


0

你也可以在SQL中简单地使用TRIM:

SELECT TRIM(myfield) as NewField

这个技巧在Lazarus中也适用。

0
一个看似简单的解决方案是使用类似于VARCHAR(n)的列类型来限制字段中TEXT的长度,其中n是允许的最大字符数。

0
如在IRC上所说,您可能需要将查询的字段添加到表单中(以便为它们生成“字段”组件),然后实现TMemoField.GetText事件。
请查看是否在对象检查器中输入“fields”字段会弹出一个编辑器来生成组件(在Zeos中是这样做的)。

我不太明白这个答案。我有同样的问题,但我正在使用Postgres。我应该做什么?你能详细解释一下吗?谢谢! - itsols

0
经过一些测试,我发现尽管这些字段被视为“MEMO”,但对于“string”字段,在创建表时仍然只需保留“VARCHAR”选项,而不是选择“TEXT”。

您的答案可以通过提供更多支持信息来改进。请[编辑]以添加更多细节,例如引用或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关编写好答案的更多信息。 - Community

0

如果是 Oracle 数据库,更改 Tquery 并放入 select 字符串 .... 将字段转换为 varchar2(100) 类型的字段 ....


0

我在MySQL和Tgrid中都有同样的问题,所以我希望答案也是相同的,因为它非常简单 :-)

假设s是导致问题的字段,那么不要写

SELECT s

编写

SELECT LEFT(s,200) AS s 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接