【问题标题】:Lazarus: DBGrid showing "(MEMO)" as the value of string fields in SQLite 3Lazarus:DBGrid 将“(MEMO)”显示​​为 SQLite 3 中字符串字段的值
【发布时间】:2011-01-26 19:52:38
【问题描述】:

我正在尝试使用 Lazarus 和 SQLdb 组件编写一个简单的 SQLite 3 应用程序。

我已成功连接到数据库并填充了TDBGrid。问题是所有作为文本字段的列都显示值“(MEMO)”而不是数据库中的字符串。

【问题讨论】:

  • 更改数据库中的列类型可解决此问题,请参阅my answer

标签: delphi sqlite lazarus memo


【解决方案1】:

我找到了一个简单的解决方案:

必须启用来自DBGrid 的属性dgDisplayMemoText。

【讨论】:

    【解决方案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 控件,并在 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 项目/字段的索引号。

    【讨论】:

      【解决方案3】:

      另一种选择

      如果您使用的是 TZConection,请在连接数据库时将此行添加到您的代码中

      TZConnection).Properties.Add('Undefined_Varchar_AsString_Length=100'); 
      

      【讨论】:

        【解决方案4】:

        正如 IRC 上所说,您可能需要将查询的字段添加到表单中(以便为它们生成“字段”组件),然后实现 TMemoField.GetText 事件。

        查看在对象检查器中输入“字段”字段是否会打开一个编辑器来生成组件(它在 Zeos iirc 中这样做)。

        【讨论】:

        • 我不太明白这个答案。我有同样的问题,但我正在使用 postgres。我究竟应该怎么做?你能详细说明一下吗?谢谢!
        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          我在 MySQL 和 Tgrid 中也有同样的情况,所以我希望答案是一样的,因为它很简单 :-)

          说如果 s 是导致问题的字段 then 而不是写

          SELECT s
          

          写

          SELECT LEFT(s,200) AS s 
          

          【讨论】:

            【解决方案7】:

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

            【讨论】:

              【解决方案8】:

              老问题,但我在寻找类似问题时遇到了它,但在通过代码而不是 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,因为那里只有一种文本类型。

              【讨论】:

                【解决方案9】:

                本文给出解决方案:Displaying and editing MEMO fiels in Delphi's TDBGrid。

                这里我总结一下你要做的事情:

                • 在.dfm 中将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;
                  

                【讨论】:

                • 为什么需要在.dfm中添加?如果您有一个持久字段,您可以在结构视图(或对象检查器顶部的下拉列表)中选择该字段并使用对象检查器的事件选项卡来执行此操作,IDE 将生成事件处理程序的存根代码给你。
                • @KenWhite 谢谢肯,你可能是对的,虽然我现在不能检查
                猜你喜欢
                • 2018-03-27
                • 2013-01-15
                • 2012-07-29
                • 1970-01-01
                • 2020-01-22
                • 1970-01-01
                • 1970-01-01
                • 2019-08-22
                • 1970-01-01
                相关资源
                最近更新 更多