Для того чтобы обратится к отдельной переменной нужно получить интерфейс ITreePinHlp. Если нужно найти переменную по полному имени, то нужно выполнить команду:
var item = (ITreePinHlp)HostFB.TreeItemHlp.Project.Item("Объект.Объект 1.Объект 1.Значение 1"); |
var ItemValue=(double?)(item.GetRTPin().ObjectValue); |
Если нужно найти переменную находящуюся на одном уровне со скриптом, то нужно вызвать метод GetChildкласса ParentObject:
var item =(ITreePinHlp)HostFB.TreeItemHlp.ParentObject.GetChild("Значение 1"); |
Например, необходимо сохранить в CSV файл параметры значений – их имена, текущее значение и метку времени.
Создадим в объекте несколько значений с произвольными именами, а также скрипт. Скрипт будет содержать два входа: «Записать» - по переднему фронту на этом входе произойдет запись данных в файл, «ПутьФайла» - путь файла, куда будут сохраняться данные, а также выход для сигнала ошибки.


public partial class ФБ : ScriptBase { bool? M=false; public override void Execute() { if (Записать==true && M==false) { } M=Записать; } } } |
string dtstring=DateTime.Now.ToString(); |
if (Записать==true && M==false) { string dtstring=DateTime.Now.ToString(); using(var file = new StreamWriter(ПутьФайла, false, Encoding.GetEncoding("windows-1251"))) //открытие файла для записи { } } M=Записать; |
using(var file = new StreamWriter(ПутьФайла, false, Encoding.GetEncoding("windows-1251"))) //открытие файла для записи { //перебор всех значений данного объекта HostFB.TreeItemHlp.Parent.NavigateChilds(delegate(ITreeObjectHlp item) { if (item.ObjectType != EObjectType.otValue) return true; ITreePinHlp command = (ITreePinHlp) item; string objValue = (command.GetRTPin().ObjectValue).ToString(); file.WriteLine("{0};{1};{2}", command.Name,dtstring,objValue); //записываем в файл return true; }, TreeItemMask.Pin, NavigateItemsFlags.CurrentComputer); } |
Рассмотрим код построчно. В метод NavigateChilds передается три параметра – делегат, вызываемый для каждого дочернего элемента, тип искомых элементов (TreeItemMask.Pin), флаги поиска. Про делегат поговорим ниже и сначала разберем последние два параметра. TreeItemMask.Pin – определяет среди каких элементов проекта нужно выполнять поиск. Pin – это элементы тип входа - «Значение» и «Вход». Можно также задать Pout (выходы, команды), Parser (Расчет), Event (Событие), FuncBlock (функциональный блок), All (все) и другие варианты. NavigateItemsFlags.CurrentComputer – флаги, определяющие пространство поиска переменных, в данном случае – только на текущем компьютере.
Теперь рассмотрим делегат. Делегат вызывается для каждого дочернего элемента (item), если делегат вернет false, перебор останавливается. Далее следует лямда-выражение которое описывает работу делегата – именно в нем мы и выполняем перебор нужных нам переменных. Разберем это выражение построчно.
В первой строке мы проверяем нужный ли тип переменной проекта мы получили:
if (item.ObjectType != EObjectType.otValue) return true; |
Поскольку метод NavigateChilds при параметре TreeItemMask.Pin возвращает как значения, так и входы, то нам нужно дополнительно убедиться, что мы получили именно значение. Для это тип полученной переменной проверяется с типом otValue (значение), и если они не совпадают, то выполняется оператор return true, происходит выход из функции и NavigateChilds переходит к следующей переменной объекта.
ITreePinHlp command = (ITreePinHlp) item; string objValue = (command.GetRTPin().ObjectValue).ToString(); |
Чтобы получить значение переменной, item сначала приводится к типу ITreePinHlp, а затем с помощью метода GetRTPin извлекается текущее значение переменное, которое преобразуется в строку методом ToString().
file.WriteLine("{0};{1};{2}", command.Name,dtstring,objValue); //записываем в файл |
Теперь, когда значение нам известно, можно произвести запись в файл методом WriteLine. Мы запишем в файл имя переменной (command.Name), время (dtstring) и непосредственно значение (objValue).
Обратите внимание на конкатенацию (объединение строк) в методе записи в файл. Первым аргументом метода передается строка форматирования – мы будем записывать 3 параметра разделенным символом «точка с запятой», затем перечислены непосредственно 3 переменных, чьи значения будут подставлены в строку. Конечно можно выполнить слияние строк и с помощью оператора «+», но подобная запись более простая. Подробнее про такой способ конкатенации можно посмотреть здесь:
https://msdn.microsoft.com/ru-ru/library/system.string.format(v=vs.110).aspx#Starting
После того как запись произведена выполняется return true – происходит переход к следующей переменной объекта.
Полный код скрипта:
public partial class ФБ : ScriptBase { bool? M=false; public override void Execute() { if (Записать==true && M==false) { string dtstring=DateTime.Now.ToString(); using(var file = new StreamWriter(ПутьФайла, false, Encoding.GetEncoding("windows-1251"))) //открытие файла для записи { //перебор всех значений данного объекта HostFB.TreeItemHlp.Parent.NavigateChilds(delegate(ITreeObjectHlp item) { if (item.ObjectType != EObjectType.otValue) return true; ITreePinHlp command = (ITreePinHlp) item; string objValue = (command.GetRTPin().ObjectValue).ToString(); file.WriteLine("{0};{1};{2}", command.Name,dtstring,objValue); //записываем в файл return true; }, TreeItemMask.Pin, NavigateItemsFlags.CurrentComputer); } } M=Записать; } } |
Сначала, нужно определится с поиском – где и переменные каких типов вы ищете. Если вы вызываете метод NavigateChilds у HostFB.TreeItemHlp.Parent, то вы выполняете поиск в объекте где находится скрипт и всех его подообъектов. Если нужно произвести поиск во всем проекте, то метод вызывается у HostFB.TreeItemHlp.Project. С помощью второго аргумента метода NavigateChilds вы определяете переменные какого типа вас интересуют (входы, выходы, расчеты или все переменные).
Затем нужно адаптировать код в лямбда-функции. Если нужно – вначале выполнить дополнительную проверку на тип возвращенной переменной, и, если она вам неинтересна, выполнить return true.
После преобразования переменной к типу ITreePinHlp, можно работать со значением, меткой времени и качеством. В нашем примере значение переменной преобразовывалось в строку. Если нужно получить конкретный тип, например, Double, то преобразование можно выполнить так:
double objValue = Convert.ToDouble(command.GetRTPin().ObjectValue); |
if (objValue is string) return true; |
Пример описанного скрипта можно скачать по ссылке. Скрипт несколько расширен – реализовано создание папки для сохранения файла, а также контроль выполнения кода с помощью операторов try-catch, при этом в случае возникновения ошибки информация пишется в лог скады с помощью метода ReportError.