1

有一段时间我一直在尝试用 c# 制作一个独立的程序,它使用 iHistorian_SDK 的 BrowseTags 函数。(iFix 5.8 和 Historian 7.0)

首先,我在 VBA 中创建了这个函数,它工作得很好,但是由于 VBA 是单线程的,我想将它从 VBA 中移除。

我今天有效的 VBA 代码:

Public connectedServer As Object
Public myServerManager As Object


Private Sub TestBrowseFunction()    
    Call BrowseTagsFromHistorianCollector("SVNF-IFIX-HIS01", "SVNF-IFIX-SCA01_iFIX")    
End Sub

Public Function BrowseTagsFromHistorianCollector(ByVal HistServer As String, ByVal HistCollector As String, Optional AdditionsOnly As Boolean = False, Optional SourceFilter As String = "*", Optional DescriptionFilter As String = "*")
    On Error Resume Next
    Dim MyTags As Variant
    Dim Tag As Variant

    Set connectedServer = Nothing
    Set MyServerManager = CreateObject("iHistorian_SDK.ServerManager")
    DoEvents

    'Make sure Historian is installed correctly'
    If MyServerManager Is Nothing Then
        Err.Raise 0, , "Error Creating iHistorian Server Manager - please check to see if Historain Client is correctly installed on your system", vbOKOnly, "test"
        Exit Function
    End If

    'Create iHistorian server object'
    Set connectedServer = CreateObject("iHistorian_SDK.Server")

    'Check to see if the connection is established, else connect.'
    If CheckConnection = False Then connectedServer.Connect (HistServer)
    If CheckConnection = True Then

        'Browse the collector for tags.'
        Set MyTags = connectedServer.collectors.Item(HistCollector).BrowseTags(AdditionsOnly, SourceFilter, DescriptionFilter)

        'Loop all the tags from the collector'
        For Each Tag In MyTags.Item
            'INSERT CODE TO DO FOR EACH TAG HERE!'
            Debug.Print Tag.tagName
        Next

    End If

End Function



' make sure that we are connected to a server'
Public Function CheckConnection() As Boolean
    On Error GoTo errc

    If connectedServer Is Nothing Then
        CheckConnection = False
        Exit Function
    End If

    If Not connectedServer.Connected Then
        CheckConnection = False
        Exit Function
    End If

    If connectedServer.ServerTime < CDate("1/1/1970") Then
        CheckConnection = False
        Exit Function
    End If

    CheckConnection = True
Exit Function

errc:
  CheckConnection = False
End Function

这很好用。但是在我尝试将相同的函数转换为 C# 时,我不断收到错误。

首先,我连接到我的历史服务器,这非常轻松。

            tsStatus.Text = "Connecting to " + HistServer;
            try
            {
                connectedServer = new iHistorian_SDK.Server();
                connectedServer.Connect(HistServer);
                tsStatus.Text = "Connected to " + HistServer;
            }
            catch (Exception ex)
            {
                Debug.Print("Server connection threw exception: " + ex);
                tsStatus.Text = "Failed connecting to " + HistServer;
            }

我尝试连接之前的状态标签:

连接前

我尝试连接后的状态标签:

连接后

建立连接后,我希望能够做一些类似于我在 VBA 中所做的事情。

Set MyTags = connectedServer.collectors.Item(HistCollector).BrowseTags(AdditionsOnly, SourceFilter, DescriptionFilter)

我的 c# 尝试如下

            iHistorian_SDK.TagRecordset MyTags;
            MyTags = new iHistorian_SDK.TagRecordset();

            MyTags = connectedServer.Collectors.Item("SVNF-IFIX-SCA01_iFIX").BrowseTags(false, "*", "*");

错误

有谁知道我可以如何解决这个问题,或者是否可以在 C# 中使用与收集器对象相同的方法浏览标签。

我看过这个视频几次,所以我认为这是可能的,他们只是跳过了他们实际浏览标签的代码。

提前致谢/T

4

2 回答 2

0

如果您检查您提供的视频链接的源代码(即客户端 SDK 示例),他们没有使用收集器来查询标签。

cmdBrowseTags_Click 正在使用 ITags“查询”方法来“浏览标签”。

以下是“iHistClientAccessAPI.chm”中包含的 GE 提供的帮助文档示例:

TagQueryParams query = new TagQueryParams();
List<Tag> list = new List<Tag>(), temp = null;

query.Criteria.TagnameMask = "*";

// simple query
connection.ITags.Query(ref query, out list);

// paged query
list.Clear();
query.PageSize = 100; // return at most 100 results per request
while (connection.ITags.Query(ref query, out temp))
  list.AddRange(temp);
list.AddRange(temp);

我更喜欢这样的东西(包括完整的服务器连接):

ServerConnection serverConnection = new ServerConnection(
new ConnectionProperties
{
    ServerHostName = "MyHistorianHostName",
    Username = "MyUserName",
    Password = "MyPassword",
    ServerCertificateValidationMode = CertificateValidationMode.None
});

serverConnection.Connect();

if (serverConnection.IsConnected())
{
    List<Tag> tagList = new List<Tag>();
    TagQueryParams tagQueryParams = new TagQueryParams
    {
        Criteria = new TagCriteria { TagnameMask = "*" }, // Wilcard, get all tags.
        Categories = Tag.Categories.All, // Change this to Basic fo mimimal info.
        PageSize = 100 // The batch size of the while loop below..
    };

    bool isQuery = true;
    while (isQuery)
    {
        isQuery = serverConnection.ITags.Query(ref tagQueryParams, out var tags);
        tagList.AddRange(tags);
    }

    // At this point, tagList contains a list of all tags that matched your wildcard filter.
    // To filter to a specific collector, you could then do something like:
    var collectorTagList = tagList.Where(t => t.CollectorName == "MyCollector");
}

祝你好运 :)

于 2018-07-19T00:16:01.920 回答
0

VBA 中的括号是一个索引器。尝试替换.Collectors.Item.("...").Collectors.Item.["..."]

于 2018-07-18T13:36:48.570 回答