Возможна ли непрямая адресация в VBS ?
Возможна ли непрямая адресация в VBS ?
Всем привет !
Нужно написать 30 одинаковых скриптов для 30 групп тегов. Каждая группа тегов состоит из 3-х уникальных внутренних тегов панели и относится к соответствующему тегу ПЛК, который будет для каждого соответствующего скрипта «входным». В скрипте необходимо производить простые арифметические и сравнительные действия.
Можно сделать 30 разных скриптов с прямой адресацией.
Но можно ли сделать только один VBS-скрипт, в котором можно было бы применить непрямую адресацию и «цикл», чтобы минимизировать размер кода.
Думаю, что тогда эти 30 групп тегов можно было бы по очереди вызывать и вставлять в скрипт как «входы» / «выходы».
Если не трудно, покажите, пожалуйста, как будет выглядеть конструкция такого «универсального» VBS-скрипта, или где можно найти пример.
Заранее благодарен.
Нужно написать 30 одинаковых скриптов для 30 групп тегов. Каждая группа тегов состоит из 3-х уникальных внутренних тегов панели и относится к соответствующему тегу ПЛК, который будет для каждого соответствующего скрипта «входным». В скрипте необходимо производить простые арифметические и сравнительные действия.
Можно сделать 30 разных скриптов с прямой адресацией.
Но можно ли сделать только один VBS-скрипт, в котором можно было бы применить непрямую адресацию и «цикл», чтобы минимизировать размер кода.
Думаю, что тогда эти 30 групп тегов можно было бы по очереди вызывать и вставлять в скрипт как «входы» / «выходы».
Если не трудно, покажите, пожалуйста, как будет выглядеть конструкция такого «универсального» VBS-скрипта, или где можно найти пример.
Заранее благодарен.
Re: Возможна ли непрямая адресация в VBS ?
Не знаю как в WinCC (кстати, какая версия и какая панель?). Но переадресацию можно сделать в ПЛК. Нет?
Или напишите скрипт, добавив в вызов скрипта аргумент-номер скрипта. А потом с помощью case дергайте те данные, которые соответствуют номеру.
Или напишите скрипт, добавив в вызов скрипта аргумент-номер скрипта. А потом с помощью case дергайте те данные, которые соответствуют номеру.
Re: Возможна ли непрямая адресация в VBS ?
Спасибо за ответ.
Да, и такой вариант с PLC тоже держу про запас.
Но пока хочу это сделать в панели на VBS, т.к. TIA-проект делался взамен старой панели и проект был для "старого" PLC S7-300 и STEP7. Не хочется пока возиться с конвертацией и добавлением кучей новых тэгов.
Проектные изменения я гружу в CPU со старого программатора, на который TIA-портал ну никак не поставить. Поэтому "контроллерная" часть - у меня в STEP7 v.5.5 , а "панельная" часть - в TIA.
Есть какой-нибудь примерчик с "case" -сом ?
Да, и такой вариант с PLC тоже держу про запас.
Но пока хочу это сделать в панели на VBS, т.к. TIA-проект делался взамен старой панели и проект был для "старого" PLC S7-300 и STEP7. Не хочется пока возиться с конвертацией и добавлением кучей новых тэгов.
Проектные изменения я гружу в CPU со старого программатора, на который TIA-портал ну никак не поставить. Поэтому "контроллерная" часть - у меня в STEP7 v.5.5 , а "панельная" часть - в TIA.
"Какэто, какэто" , как сказал то ли Ильченко Карцеву, то ли Карцев Ильченко в одной из реприз.Или напишите скрипт, добавив в вызов скрипта аргумент-номер скрипта. А потом с помощью case дергайте те данные, которые соответствуют номеру.
Есть какой-нибудь примерчик с "case" -сом ?
Re: Возможна ли непрямая адресация в VBS ?
Вот пример кода:
Код: Выделить всё
Sub VBFunction_1(ByVal Number)
Select Case Number
Case 1
SetTag(Tag_1,True);
Case 2
SetTag(Tag_2,True);
Case 3
SetTag(Tag_3,True);
Case Else
SetTag(Tag_n,True);
End Select
End Sub
Потом, когда вы будете вызывать подпрограмму, укажите тот или иной Number. В моем случае это числа 1, 2, 3. В зависимости от значения Number производится одно из трех разных действий. Четвертое действие (Case Else) выполняется, если Number не равно 1, 2, 3.
В Вашем случае внутри select-case-блока нужно разместить считывание каких-то ваших разных тегов, сохранение в переменную.
Способ 2. Поинтереснее:
Код: Выделить всё
Sub VBFunction_1(ByRef Tag)
SetTag(Tag, 100);
End Sub
P.S. В обоих случаях для VB-функции или подпрограммы используется параметр. Задается в свойствах функции или подпрограммы. Параметров можно задать несколько.
Re: Возможна ли непрямая адресация в VBS ?
Если я правильно понял, то сначала создаётся подпрограмма "VBFunction_1", которая потом будет вызываться те же 30 раз, но только аргументы будут в ней указаны через "Number" ?
Если так, то по размеру кода получится, наверное, то же самое.
А "цикл" тут можно будет вставить ?
С ним бы как раз всё и получилось максимально компактно.
Если поконкретнее, то оставил 3 тэга и написал, что должны делать скрипты.
Тут ниже 30 раз значение тэга "VAR_*_IN" переписывается в тэг "VAR_*_OUT", только если тэг VAR_*.1 = «1»
Temp1 = SmartTags("VAR_1_IN")
If SmartTags("VAR_1.1") = 1
then SmartTags("VAR_1_OUT") = Temp1
Temp2 = SmartTags("VAR_2_IN")
If SmartTags("VAR_2.1") = 1
then SmartTags("VAR_2_OUT") = Temp2
…………………………….……….
…………………………….……….
Temp30 = SmartTags("VAR_30_IN")
If SmartTags("VAR_30.1") = 1
then SmartTags("VAR_30_OUT") = Temp30
Теперь как сделать один универсальный скрипт со счётчиком циклов и подстановкой тэгов "VAR_*_IN" ; "VAR_*_OUT" ; «VAR_*.1», чтобы код был максимально компактным ?
Если так, то по размеру кода получится, наверное, то же самое.
А "цикл" тут можно будет вставить ?
С ним бы как раз всё и получилось максимально компактно.
Если поконкретнее, то оставил 3 тэга и написал, что должны делать скрипты.
Тут ниже 30 раз значение тэга "VAR_*_IN" переписывается в тэг "VAR_*_OUT", только если тэг VAR_*.1 = «1»
Temp1 = SmartTags("VAR_1_IN")
If SmartTags("VAR_1.1") = 1
then SmartTags("VAR_1_OUT") = Temp1
Temp2 = SmartTags("VAR_2_IN")
If SmartTags("VAR_2.1") = 1
then SmartTags("VAR_2_OUT") = Temp2
…………………………….……….
…………………………….……….
Temp30 = SmartTags("VAR_30_IN")
If SmartTags("VAR_30.1") = 1
then SmartTags("VAR_30_OUT") = Temp30
Теперь как сделать один универсальный скрипт со счётчиком циклов и подстановкой тэгов "VAR_*_IN" ; "VAR_*_OUT" ; «VAR_*.1», чтобы код был максимально компактным ?
Re: Возможна ли непрямая адресация в VBS ?
Воспользуйтесь способом №2. Создайте подпрограмму. Задайте три параметра ByRef: Condition, In и Out.
SmartTags() не используйте, обращайтесь напрямую к параметрам. А эти параметры при вызове подпрограммы подцепите к соответствующим HMI tags.
SmartTags() не используйте, обращайтесь напрямую к параметрам. А эти параметры при вызове подпрограммы подцепите к соответствующим HMI tags.
Код: Выделить всё
Sub VBFunction_1(ByRef Condition, ByRef Input, ByRef Output)
If Condition = 1
Then Output = Input
End Sub
Re: Возможна ли непрямая адресация в VBS ?
У вас должно быть 30 разных вызовов, но один очень маленький скриптик.
30 вызовов можно засунуть в отдельный скрипт (см. ниже).
Примерно так. Не совсем знаю, что такое SmartTags().
30 вызовов можно засунуть в отдельный скрипт (см. ниже).
Код: Выделить всё
Sub VBFunction_2()
VBFunction_1(VAR_1.1, VAR_1_IN, VAR_1_OUT)
VBFunction_1(VAR_2.1, VAR_2_IN, VAR_2_OUT)
VBFunction_1(VAR_3.1, VAR_3_IN, VAR_3_OUT)
VBFunction_1(VAR_4.1, VAR_4_IN, VAR_4_OUT)
VBFunction_1(VAR_30.1, VAR_30_IN, VAR_30_OUT)
End Sub
Re: Возможна ли непрямая адресация в VBS ?
Спасибо, попробую.
Насколько я понял ранее, конструкция SmartTags() работает так.
Язык VBS не может напрямую «понимать» HMI-тэги. Причём как «внутренние», так и «внешние» (контроллерные). Поэтому, чтобы «затащить» их в VBS и используется конструкция SmartTags().
Temp2 = SmartTags("VAR_2_IN") \\ Тут переменной Temp2 языка VBS
присваивается значение HMI-тэга «VAR_2_IN». Причём при такой записи даже не обязательно в начале текста программы Sub (или Function) декларировать переменную Temp2 с помощью команды Dim.
Можно, конечно, использовать стандартные команды Dim, Set , чтобы создать объект «Tag» языка VBS с именем «Temp2», с присущими для него свойствами, но в данном случае мне от тэга нужно только его единственное свойство, а именно свойство «Value». К тому же мне тут не нужно привязывать этот тэг к какому-нибудь "I\O field" на каком-нибудь экране.
Т.е. запись, для интересующего меня тэга, получается максимально компактной.
Насколько я понял ранее, конструкция SmartTags() работает так.
Язык VBS не может напрямую «понимать» HMI-тэги. Причём как «внутренние», так и «внешние» (контроллерные). Поэтому, чтобы «затащить» их в VBS и используется конструкция SmartTags().
Temp2 = SmartTags("VAR_2_IN") \\ Тут переменной Temp2 языка VBS
присваивается значение HMI-тэга «VAR_2_IN». Причём при такой записи даже не обязательно в начале текста программы Sub (или Function) декларировать переменную Temp2 с помощью команды Dim.
Можно, конечно, использовать стандартные команды Dim, Set , чтобы создать объект «Tag» языка VBS с именем «Temp2», с присущими для него свойствами, но в данном случае мне от тэга нужно только его единственное свойство, а именно свойство «Value». К тому же мне тут не нужно привязывать этот тэг к какому-нибудь "I\O field" на каком-нибудь экране.
Т.е. запись, для интересующего меня тэга, получается максимально компактной.
Re: Возможна ли непрямая адресация в VBS ?
Навроде как. Спасибо.
Также, думаю, что мне очень поможет такая штука :
тут тэги не мои, из другого примера
Dim i
Dim tag
for i = 0 to 30 step 1
set tag = HMIRuntime.SmartTags("tagName_" & i & "_PV")
tag.value = something \\ какая-то формула (лы), которая формирует значение данного тэга "tagName_" & i & "_PV"
next
Знак & является знаком конкатенации (т.е. слияния). С его помощью происходит слияние двух частей какого-то текста . В данном случае эти части = разделённому имени тэга. Разделение попало на «число». Т.е. на то единственное, чем эти дофига тэгов друг от друга отличаются.
Если «слить», то получится
tagName_ i_PV
и если теперь подставить вместо индекса (1,2,3….30) , то получим :
tagName_ 1_PV
tagName_ 2_PV
tagName_ 3_PV
............................
tagName_30_PV
Так что, видимо, придётся кроме упрощённого "SmartTags()" использовать и "усложнённые" Dim, Set и прочее "чарующе-завораживающие" хитрости языка VBS
Вобщем, теперь знаю, куда копать.
Т.е. "отсюда и до обеда"
Re: Возможна ли непрямая адресация в VBS ?
Создал 2 скрипта :
Первый – это функция Function MainOUT (ByVal id) , где и происходят все вычисления
Второй сделан на Sub , внутри которого вызывается функция MainOUT с ин-дексом "i" и оператором "For i = 1 to <нужное мне количество раз> NEXT".
Всё работает НО есть проблема.
Внутри Function MainOUT я создал условие при котором скрипт может не доработать до конца и выходит по команде Exit
If FilterEnbl = 0 Then Exit Function
Т.е. если тут битовый тэг FilterEnbl = 0, то скрипту нет смысла работать до конца и грузить процессор панели.
У меня, к примеру, 30 датчиков. Один сломан и я для него кнопкой на панели установил FilterEnbl = 0 . И тогда скрипты для всех остальных датчиков перестают работать.
При этом на панель выдаётся системное сообщение «Ошибка. Переполнение в сценарии «Filters» в строке 12» .
Второй скрипт, который на Sub
Dim i
For i= 1 To 30
SmartTags("Main_" & i & "_OUT") =MainOUT (i)
Next
Можно ли что-то сделать, чтобы это локальное условие FilterEnbl = 0 для одного датчика не влияло на работу всех скриптов ?
Или придётся убирать его из функции Function MainOUT ?
И тогда каждому «локальному» скрипту всегда придётся отрабатывать до кон«Wi-Fi».
SmartTags("Main_" & i & "_OUT") =MainOUT (i) - это как раз и есть та 12-я строка
Первый – это функция Function MainOUT (ByVal id) , где и происходят все вычисления
Второй сделан на Sub , внутри которого вызывается функция MainOUT с ин-дексом "i" и оператором "For i = 1 to <нужное мне количество раз> NEXT".
Всё работает НО есть проблема.
Внутри Function MainOUT я создал условие при котором скрипт может не доработать до конца и выходит по команде Exit
If FilterEnbl = 0 Then Exit Function
Т.е. если тут битовый тэг FilterEnbl = 0, то скрипту нет смысла работать до конца и грузить процессор панели.
У меня, к примеру, 30 датчиков. Один сломан и я для него кнопкой на панели установил FilterEnbl = 0 . И тогда скрипты для всех остальных датчиков перестают работать.
При этом на панель выдаётся системное сообщение «Ошибка. Переполнение в сценарии «Filters» в строке 12» .
Второй скрипт, который на Sub
Dim i
For i= 1 To 30
SmartTags("Main_" & i & "_OUT") =MainOUT (i)
Next
Можно ли что-то сделать, чтобы это локальное условие FilterEnbl = 0 для одного датчика не влияло на работу всех скриптов ?
Или придётся убирать его из функции Function MainOUT ?
И тогда каждому «локальному» скрипту всегда придётся отрабатывать до кон«Wi-Fi».
SmartTags("Main_" & i & "_OUT") =MainOUT (i) - это как раз и есть та 12-я строка
Re: Возможна ли непрямая адресация в VBS ?
Поясните, что за ошибка? Почему она возникает?
Я полагаю просто нужно запускать код в строке 12 по условию if (FilterEnbl = 1)
Я полагаю просто нужно запускать код в строке 12 по условию if (FilterEnbl = 1)
Re: Возможна ли непрямая адресация в VBS ?
Вот код функции MainOUT :
Function MainOUT(ByVal id)
Dim FilterEnbl, LogIN, DeadBand, LogOUTprev, LogOUT, HLDB, LLDB
FilterEnbl = SmartTags("Filter_" & id & "_Enbl")
If FilterEnbl = 0 Then Exit Function
LogIN = SmartTags("Log" & id & "IN")
<bla...bla...bla>
End Function
Там, где <bla...bla...bla> - всё правильно.
Например, я для датчика 1 выставил бит FilterEnbl = 0
Тогда, после запуска скрипта
Dim i
For i= 1 To 30
SmartTags("Main_" & i & "_OUT") =MainOUT (i)
Next
он обратится к функции MainOUT, где ей в индекс "i" подставится "1" -ца. Т.е. функция MainOUT вызовется с id = 1, т.е. начнёт обрабатывать свой код для датчика №1.
Дойдя до условия FilterEnbl = 0 (т.к. я его выставил в "0")
If FilterEnbl = 0 Then Exit Function
произойдёт выход из функции MainOUT (1).
Я то ожидал, что выйдет и дальше пойдёт, к датчику 2, т.е. подставит MainOUT (2). Но вероятно этого не происходит, т.к. выдаётся сообщение об ошибке и глобальный скрипт не выполняется.
Function MainOUT(ByVal id)
Dim FilterEnbl, LogIN, DeadBand, LogOUTprev, LogOUT, HLDB, LLDB
FilterEnbl = SmartTags("Filter_" & id & "_Enbl")
If FilterEnbl = 0 Then Exit Function
LogIN = SmartTags("Log" & id & "IN")
<bla...bla...bla>
End Function
Там, где <bla...bla...bla> - всё правильно.
Например, я для датчика 1 выставил бит FilterEnbl = 0
Тогда, после запуска скрипта
Dim i
For i= 1 To 30
SmartTags("Main_" & i & "_OUT") =MainOUT (i)
Next
он обратится к функции MainOUT, где ей в индекс "i" подставится "1" -ца. Т.е. функция MainOUT вызовется с id = 1, т.е. начнёт обрабатывать свой код для датчика №1.
Дойдя до условия FilterEnbl = 0 (т.к. я его выставил в "0")
If FilterEnbl = 0 Then Exit Function
произойдёт выход из функции MainOUT (1).
Я то ожидал, что выйдет и дальше пойдёт, к датчику 2, т.е. подставит MainOUT (2). Но вероятно этого не происходит, т.к. выдаётся сообщение об ошибке и глобальный скрипт не выполняется.
Re: Возможна ли непрямая адресация в VBS ?
А вы не выходите из функции, а просто с помощью того же if просто пропустите присвоение и блаблабла.
Re: Возможна ли непрямая адресация в VBS ?
Так ить задумка и была, чтобы не выполнять скрипт до самого конца для конкретного датчика, если для этого датчика в данный момент и в ближайший месяц-два это и не требуется. Т.е. выставляю кнопкой бит "FilterEnable = 0", что запретит работу скрипта для данного датчика и не будет излишне нагружать процессор HMI.
Т.е. "бла-бла-бла" не всегда нужно
Т.е. "бла-бла-бла" не всегда нужно
Re: Возможна ли непрямая адресация в VBS ?
Если условие if не выполняется и блаблабла пропускается, то процессор не нагружается.