【问题标题】:VB.NET Dynamically creating variables at runtimeVB.NET 在运行时动态创建变量
【发布时间】:2015-08-11 12:04:40
【问题描述】:

我想在我的应用程序启动时或从内部调用时在运行时创建变量。此要求的情况是我正在从站点上的各种设备读取数据,目前这是在应用程序中硬编码的。我想做的是创建一个应用程序,该应用程序从所需变量的数据库中加载列表并根据需要创建和分配它们。

我正在使用 INGEAR 驱动程序包来读取数据,我需要声明多个 PLC,对于每个 PLC,我需要声明多个 ScanGroup,每个 ScanGroup 将有多个标签。读取的数据将在每次读取时写入数据库。

在设计时声明每一个(来自 INGEAR 提供的示例应用程序)是

    ' *****************************
' * Initialize Controller class
Public MyPLC As New Controller

' ******************************
' * Initialize TagGroup class
Public scanGroup As New TagGroup

' ******************************
' * un-initialized Tag class
Dim WithEvents newTag As Tag

使用“WithEvents”,他们可以动态创建标签,但不能 100% 确定它是如何工作的以及如何进一步实现。

当他们在应用程序运行时添加标签时,他们会做一些事情:

newTag = New Tag(MyPLC, _tagName.Text)

还有

AddHandler newTag.Changed, AddressOf newTag_Changed

我假设它用于捕获更改(并从线程调用)

有没有人可以给我一些指导:

  • 如何在运行时从列表/数组/结构中声明我的 PLC
  • 如何在运行时为每个 PLC 声明扫描组(这些被称为每个 PLC 都有一个集合)
  • 如何在运行时添加标签。

我假设该示例正朝着正确的方向发展,但不能 100% 确定每个项目要达到的目标。 如果有人想了解有关应用程序/示例的更多详细信息,请告诉我。

附加

因此,通过这段代码,我假设在我的数据库中有 3 个表。

PLC Table - PLC_ID, PLC Name, PLC_IPaddress
SCAN Group - GROUP_ID, Group_Name, Group_Time
TAGS - TAG_ID, PLC_ID, GROUP_ID, Tag_Value

变量:

Dim ALLPLCs As New Dictionary(Of String, Controller)
Dim ScanGroups As New Dictionary(Of String, TagGroup)
Dim AllTags As New Dictionary(Of String, Tag)

使用以下方法创建“控制器”非常简单:

    For Each row In PLCTable.Rows
        ALLPLCs.Add(row("PLC_ID"), New Controller(row("PLC_IP"), 1000))
    Next

创建我的组如下,但开始担心项目的跟踪。这将创建一个名称,如“1_1”、“2_4”,第一个数字是 PLC_ID,第二个数字是 GROUP_ID

    For Each row In ScanGroupTable.Rows
        For Each thePLC In ALLPLCs
            Dim tg As New TagGroup
            tg.Controller = thePLC.Value
            tg.ScanningMode = TagGroup.SCANMODE.ReadOnly
            tg.Interval = Convert.ToInt16(row("GROUP_TIME"))
            ScanGroups.Add(thePLC.Key & row("GROUP_ID"), tg) 'Add the 1 second scangroup
        Next
    Next

现在下一个查询是如何将我的标签添加到每个 PLC_ID 和 GROUP_ID 的字典中。这有什么方向吗?创建静态标签时,我会按照下面的方式做一些事情,但是如何通过选择正确的 PLC 和 Scangroup 来正确地做到这一点?

 Dim tg As New Tag
    tg.Controller = "CONTROLLER"
    tg.Name = "TAG_NAME"
    ScanGroups.Add(tg)

之后,系统扫描组将自动执行线程以按其间隔进行更新。在示例项目中,动态添加标签时,使用如下:

AddHandler newTag.Changed, AddressOf newTag_Changed

这是我有点卡住的地方。如何在运行时为每个标签添加处理程序并正确捕获它们的更改

【问题讨论】:

  • 您确实应该向我们展示您正在使用的界面以及您正在加载的数据的格式 - 这会使这个问题变得更好。
  • 嗨@Enigmativity,不确定您指的是什么接口。很高兴提供与此相关的任何信息。在这个阶段,我将从每个标签接收的数据类型可以是字符串、整数或浮点数
  • 接口将是类类型以及它们支持的方法和属性的签名,并且是IDisposable等。正是Public Interface IController的代码中需要的内容例子。足以让某人编写代码来为您提供答案。
  • 控制器的所有项目都在我引用的外部库中。 (希望这就是你的意思)
  • 不,我不是这个意思。我希望能够从您的问题中复制接口的代码以便能够进行编码。像这样:Public Interface IController Function CreateTag(Tag As String) As ITag End Interface。这样我就可以将接口复制并粘贴到我的开发环境中,并能够为您编写一个可以实际编译的答案。

标签: vb.net plc


【解决方案1】:

您可以使用字典或类似结构来跟踪您创建的所有项目。

public Dictionary<string, Controller> AllPLCs { get; set; }
public Dictionary<string, TagGroup> ScanGroups { get; set; }
public Dictionary<string, WithEvents> AllNewTags { get; set; }

从这里,您可以从数据库加载并循环添加到字典中,使用名称作为字符串键。

foreach(var foundItem in LoadedData)
{
    AllPLCs.Add(foundItem.Name, new Controller());
    ScanGroups.Add(foundItem.Name, new TagGroup());
    AllNewTags.Add(foundItem.Name, new WithEvents());
}

稍后您可以按如下方式访问每一个:

foreach(var foundItem in LoadedData)
{
    Controller currentController = AllPLCs[foundItem.Name] as Controller());
    TagGroup currentGroup = ScanGroups[foundItem.Name] as TagGroup;
    WithEvents currentEvent = AllNewTags[foundItem.Name] as WithEvents;
}

我的代码示例是用 C# 编写的,但它们应该能让你走上正轨。

【讨论】:

  • 谢谢,“WithEvents”实际上是做什么的?下周有空的时候我会尝试一下。
  • 这是基于您的代码中的“Dim WithEvents newTag As Tag”。根据需要进行调整。 :)
  • 谢谢,我刚刚从提供的示例项目中复制了代码,关于如何创建每次读取所需的线程并在运行时获取结果的任何说明?
  • 搜索 BackgroundWorker。如果您需要帮助,请为它打开第二个问题。
  • 使用字典代码,我能够结合我对原始帖子的更新来完成这项工作。我不需要创建任何线程,因为 INGEAR 扫描组有它自己的功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多