将组件名称存储为字符串供以后使用

时间:2016-10-01 02:42:56

标签: delphi delphi-7

在我的表单上,我有许多TMyQuery组件。它们的名称标识了它们使用的MySQL表。例如,COMPONENTSTABLE可与COMPONENTS TABLE等一起使用

大约有30个表,但将来可能会发生变化。

我还使用基本字符串列表从名为TIMESTAMPS的表中读取字段名称。发生UPDATE,INSERT或DELETE时,此表通过触发器更新。 TIMESTAMPS表中的每个字段指的是哪个表被修改。表中只有一条记录!根据字段值,我可以看到哪个表已更改,因此我可以刷新它而不是刷新所有表。

我不想这样做;

If fieldbyname['COMPONENTSTABLE'] <> CurrentTimeStamp
 then ComponentsTable.Refresh;

If fieldbyname['ORDERSTABLE'] <> CurrentTimeStamp
 then OrdersTable.Refresh;

{ and so on forever }

我想做的是;

现在我有一个字符串列表&#34;名称/值&#34;。每个&#34;名称&#34;表中的字段名称和&#34;值&#34;是MySQL Triggers提供的TIMESTAMP。

我得到了以下内容;

For Idx := 0 to MyStringList.Count -1 do
  Begin

    If MyStringlist.ValueFromIndex[Idx] <> SomethingElse then 
     Begin
        with (MyStringList.Names[Idx] as tMyQuery).Refresh;
     End;

  End;

我有字符串列表功能,名称,值等都是正确的。

我的问题是这个;

我是否可以使用字符串(&#34;名称&#34;列表中的列)来引用对象(如果该对象存在?)

我已经有了一个函数,我通过将一个Object传递给它来刷新单个表,但它是一个对象并且易于使用。我想通过&#34;对象&#34;基于它从字符串中检索的名称。

我希望这是有道理的,你可以遵循我之后的事情。

2 个答案:

答案 0 :(得分:2)

我不确定你的问题究竟是什么。在答案的第一部分,我假设您并不真正关心对象的名称,而是想要一些自动获取所有表的方法,请参考另一个表中的字段。在此之下,如果您知道其名称,我会回答您关于引用对象的问题。

处理所有表格的自动方式

这取决于你的对象是什么类。

根据您的说明,我假设您的TMyQueryTComponent后代所拥有的表单。然后解决方案非常简单,因为每个TComponent都有公共Name和自有组件列表Components。然后你可以使用这样的东西:

var
  i: integer;
  MyQuery: TMyQuery;
begin
  for i := 0 to Pred(MyForm.ComponentCount) do
    if MyForm.Components[i] <> TimeStampsTable then
      if MyForm.Components[i] is TMyQuery then
      begin
        MyQuery := TMyQuery(MyForm.Components[i]);
        if TimeStampsTable.FieldByName(MyQuery.Name).AsDateTime >= LastAccess then ...
      end;
end;

请注意,您可能需要添加额外的支票,例如确保MyQuery.Name不为空或在TimeStampsTable中作为字段存在。

如果您的对象仅为TObject s,那么就没有&#34;标准&#34; name属性,没有这些对象的标准注册。名称可以处理,显然你的组件已经有一个,所以它只是一个正确类型强制的问题,但对象注册是另一回事。您可能必须为所有已创建的TMyQuery实例创建某种全局列表。

根据该对象的名称获取对象实例

function TMyForm.GetQueryByName(const Name: string): TMyQuery;
var
  Obj: TObject;
begin
  Result := nil;
  Obj := Self.FindComponent(Name);
  if Obj <> nil then
    if Obj is TMyQuery then
      Result := TMyQuery(Obj);
end;

或者您可以简单地遍历所有Components并使用您自己的Name匹配。

答案 1 :(得分:0)

虽然@pepak接受的答案的第一部分不是我想要的(我之前在应用程序中使用了类似的代码并发现它很慢),但答案的第二部分指出了我的右边方向。

我(感谢Pepak)最终解决方案是;

Function RefreshQueryByName(Const Name: String): Boolean;
   Var
      Obj: TComponent;
   Begin
      Result := False;
      Obj := Self.FindComponent(Name);
      If Obj <> nil Then
         If Obj Is TMyQuery Then
            With Obj As TMyQuery Do
               If Active Then
               Begin
                  Refresh;
                  Result := True;
               End;
   End;

我通过传递字符串来获取字符串,该字符串标识了我想要刷新的表。

现在,我的数据库应用程序会自动刷新其他用户更改的表。它现在将刷新其他用户修改的30个表中的任何一个表而不刷新所有表。

感谢您的帮助,Pepak,我已经接受了您的回答并希望它对其他人有用。