Метод BrowseTags (объект Collector) | VBA против C#
Некоторое время я пытался создать отдельную программу на C#, которая использует функцию BrowseTags из iHistorian_SDK. (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
2 ответа
Скобка в VBA является индексатором. Попробуй заменить .Collectors.Item.("...")
с .Collectors.Item.["..."]
Если вы проверите исходный код для предоставленной вами ссылки на видео (например, пример клиентского SDK), они не используют коллекторы для запроса тегов.
cmdBrowseTags_Click использует метод "Запрос" ITags для "просмотра тегов".
Вот пример предоставленной GE справочной документации, включенной в "iHistClientAccessAPI.chm":
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");
}
Удачи:)