将组件名称存储为字符串以备后用
Storing Component Name as a String for later use
在我的表单上有许多 TMyQuery 组件。他们的名字表明他们与哪些 MySQL Table 合作。例如,COMPONENTSTABLE 与 COMPONENTS TABLE 等一起使用
大约有 30 个 table,但将来可能会改变。
我还使用基本字符串列表从名为 TIMESTAMPS 的 Table 中读取字段名称。当更新、插入或删除发生时,此 table 通过触发器更新。 TIMESTAMPS Table 中的每个字段都指的是 Table 被修改的地方。 table中只有一条记录!根据字段值,我可以看到哪些 table 发生了变化,因此我可以刷新它而不是全部刷新。
我不想这样做;
If fieldbyname['COMPONENTSTABLE'] <> CurrentTimeStamp
then ComponentsTable.Refresh;
If fieldbyname['ORDERSTABLE'] <> CurrentTimeStamp
then OrdersTable.Refresh;
{ and so on forever }
我想做的是;
现在我有一个 "Names / Values" 的字符串列表。每个 "Name" 都是 Table 中的字段名,"Value" 是由 MySQL 触发器提供的时间戳。
我有以下内容;
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;
我的字符串列表正在运行,名称、值等都是正确的。
我的问题是这样的;
有没有一种方法可以使用字符串("Names" 列表中的列)来引用一个对象(如果该对象存在)?
我已经有了一个函数,我可以通过将对象传递给它来刷新个人 table,但这是一个对象并且易于使用。我想根据从字符串中检索到的名称传递 "Object"。
我希望这是有道理的,你可以按照我的要求去做。
我不确定你的问题到底是什么。在答案的第一部分,我假设您并不真正关心对象的名称,而是想要一些自动化的方法来获取所有可用的 table 引用另一个 table 中的字段。在此之下,如果您知道对象的名称,我将回答您关于引用该对象的问题。
自动处理所有 tables
这取决于 class 你的对象是什么。
根据您的描述,我假设您的 TMyQuery
是表单拥有的 TComponent
后代。然后解决方案非常简单,因为每个 TComponent
都有一个 public 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
,则没有 "standard" 名称 属性,也没有这些对象的标准注册。名称可以处理,显然您的组件已经有一个,所以这只是一个适当的类型强制的问题,但对象注册是另一回事。您可能必须为所有已创建的 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
匹配。
虽然@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;
我通过传递从字段值中获取的字符串来使用它,该字段值标识我要刷新的 table。
现在,我的数据库应用程序会自动刷新其他用户更改的 table。它现在将刷新被其他用户修改的 30 个 table 中的任何一个,而不刷新所有 table。
感谢Pepak的帮助,我已经接受了你的回答,希望对其他人有用。
在我的表单上有许多 TMyQuery 组件。他们的名字表明他们与哪些 MySQL Table 合作。例如,COMPONENTSTABLE 与 COMPONENTS TABLE 等一起使用
大约有 30 个 table,但将来可能会改变。
我还使用基本字符串列表从名为 TIMESTAMPS 的 Table 中读取字段名称。当更新、插入或删除发生时,此 table 通过触发器更新。 TIMESTAMPS Table 中的每个字段都指的是 Table 被修改的地方。 table中只有一条记录!根据字段值,我可以看到哪些 table 发生了变化,因此我可以刷新它而不是全部刷新。
我不想这样做;
If fieldbyname['COMPONENTSTABLE'] <> CurrentTimeStamp
then ComponentsTable.Refresh;
If fieldbyname['ORDERSTABLE'] <> CurrentTimeStamp
then OrdersTable.Refresh;
{ and so on forever }
我想做的是;
现在我有一个 "Names / Values" 的字符串列表。每个 "Name" 都是 Table 中的字段名,"Value" 是由 MySQL 触发器提供的时间戳。
我有以下内容;
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;
我的字符串列表正在运行,名称、值等都是正确的。
我的问题是这样的;
有没有一种方法可以使用字符串("Names" 列表中的列)来引用一个对象(如果该对象存在)?
我已经有了一个函数,我可以通过将对象传递给它来刷新个人 table,但这是一个对象并且易于使用。我想根据从字符串中检索到的名称传递 "Object"。
我希望这是有道理的,你可以按照我的要求去做。
我不确定你的问题到底是什么。在答案的第一部分,我假设您并不真正关心对象的名称,而是想要一些自动化的方法来获取所有可用的 table 引用另一个 table 中的字段。在此之下,如果您知道对象的名称,我将回答您关于引用该对象的问题。
自动处理所有 tables
这取决于 class 你的对象是什么。
根据您的描述,我假设您的 TMyQuery
是表单拥有的 TComponent
后代。然后解决方案非常简单,因为每个 TComponent
都有一个 public 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
,则没有 "standard" 名称 属性,也没有这些对象的标准注册。名称可以处理,显然您的组件已经有一个,所以这只是一个适当的类型强制的问题,但对象注册是另一回事。您可能必须为所有已创建的 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
匹配。
虽然@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;
我通过传递从字段值中获取的字符串来使用它,该字段值标识我要刷新的 table。
现在,我的数据库应用程序会自动刷新其他用户更改的 table。它现在将刷新被其他用户修改的 30 个 table 中的任何一个,而不刷新所有 table。
感谢Pepak的帮助,我已经接受了你的回答,希望对其他人有用。