Вопросы по скриптам в Simple-Scada 2

Автор Simple-Scada, 29 января 2016, 15:19:20

Simple-Scada

#330
Миханик, код очень странный. Формируется строка Tname, затем зачем-то берётся указатель на эту строку и приводится к типу Double (вещественное число) и с ним идёт работа. Хотя это просто указатель на ячейку в оперативной памяти ПК.

Опишите задачу которую нужно решить, а мы предложим решение. Нужно пройти по 52 переменным и среди них найти среднее, мин., макс.? Мы правильно поняли?

И ещё: откуда берётся переменная "Silosname"?

Миханик

#331
Извините, торопился, не успел подробнее описать.
Имеется 52 термоподвески, каждая из которых состоит из 29 датчиков.
Термоподвески называются T111, T112, ..., T255 (Представлены массивом Cname)
В скаде датчики термоподвески описаны как T111_01, T111_02, ..., T111_29.
Необходимо для каждой термоподвески вычислять минимальное, максимальное и среднее значение.
Silosname это Cname (проглядел при редактировании сообщения).
У меня главный вопрос как обратится к тегу по индексу в цикле скрипта?

Simple-Scada

#332
К тегам по индексу обратиться нельзя, т.к. у них нет индекса. Вместо этого нужно обращаться к переменной по имени. Для поиска переменной по имени можно воспользоваться глобальной функцией GetVariablebyName.

В Вашем случае можно избавиться от массива Cname, т.к. имена растут последовательно с 111 до 255, а значит можно генерировать их прямо в цикле.

В результате: у нас в проекте должны быть подвески от 111 до 255, каждая имеет по 29 датчиков с именами, например T111_01, T111_02... и т.д.. Также для каждой подвески есть отдельные переменные T111_min, T111_max, T111_avg в которые будем записывать минимум/максимум/среднее по датчикам. Тогда рабочий код должен быть таким:
Код: pascal
var
  I, J: Integer;
  aName, aNumber: string;
  aVar: TM_Variable;
  aVarMin, aVarMax, aVarAvg: TM_Variable;

  aVal: Double;
  aCount: Integer;
  aMin, aMax, aSum: Double;
begin
  { проход по подвескам от 111 до 255 }
  for I := 111 to 255 do
  begin
    { формируем приставку к имени текущей подвески, например "T111_" }
    aName := CharToStr('T') + IntToStr(I) + CharToStr('_');

    { сброс счетчика переменных }
    aCount := 0;

    { проход по 29 датчикам текущей подвески }
    for J := 1 to 29 do
    begin
      { получаем переменную датчика, по имени, например "T111_01" }
      if J < 10 then 
        aVar := GetVariableByName(aName + '0' + IntToStr(J))
      else
        aVar := GetVariableByName(aName + IntToStr(J));

      { если переменная с таким именем найдена }
      if aVar <> nil then 
      begin
        aVal := aVar.AsFloat;     // получаем значение переменной приведённое к типу Double
        Inc(aCount);              // увеличиваем счетчик переменных

        { далее операции для вычисления мин./макс./среднего }
        if aCount = 1 then        
        begin
          aMin := aVal;
          aMax := aVal;
          aSum := aVal;
        end else
          begin
            if aMin > aVal then aMin := aVal;
            if aMax < aVal then aMax := aVal;
            aSum := aSum + aVal;
          end;
      end;
    end;

    if aCount > 0 then
    begin
      { ищем по имени переменные мин., макс. и среднего для текущей подвески }
      aVarMin := GetVariableByName(aName + 'min');
      aVarMax := GetVariableByName(aName + 'max');
      aVarAvg := GetVariableByName(aName + 'avg');

      { записываем результаты вычислений в переменные мин., макс. и среднего }
      if aVarMin <> nil then aVarMin.Value := aMin;
      if aVarMax <> nil then aVarMax.Value := aMax;
      if aVarAvg <> nil then aVarAvg.Value := aSum / aCount;
    end;
  end;
end.
Обратите внимание, в коде выше имена будут генерироваться "T111_01", "T111_02", а не "T111_1", "T111_2" и т.д. Поэтому убедитесь, что у Вас переменные названы именно "T111_01", "T111_02".

Миханик

Большое спасибо, это то, что нужно!

makimu

Доброго времени суток, уважаемые разработчики. Интересует меня тип TM_DataSet. Если я получаю в результирующей выборке более чем одну строку, то как мне работать с этим? Как считывать построчно?

К примеру:
//Выделить все из таблицы А
Код: pascal
select * from tableA;

//Получить данные построчно C#
Код: pascal
SqlCommand command = new SqlCommand(queryString, connection);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
  // Что-то делаем, например, заполняем записями ComboBox
}

И по поводу того же ComboBox. Динамически, как я прочел, но не пробовал еще, можно добавлять строки. У ComboBox есть свойство "строка", а там свойство "Значение". Так вот, могу ли я динамически строку создать и присвоить свойству "Значение", собственно, значение динамически=) ?

Спасибо заранее.

Simple-Scada

#335
Здравствуйте.

Для перемещения курсора в наборе данных на следующую позицию используйте Next. А на предыдущую позицию - Prior. Если нужно перебрать весь набор данных, то цикл будет таким:
Код: pascal
begin
  { выполнять цикл пока не достигнем конца набора данных }
  while not DataSet.EOF do
  begin
    // здесь работаем с текущей строкой
    DataSet.Next;  // переходим на следующую строку
  end;
end.

А это тот же код, но добавлен проход по ячейкам строки:
Код: pascal
var
  I: Integer;
  aStr: string;
begin
  { выполнять цикл пока не достигнем конца набора данных }
  while not DataSet.EOF do
  begin
    { проходим по каждой ячейке текущей строки }
    for I := 0 to DataSet.FieldCount - 1 do
      aStr := DataSet[I].AsStr;  // получаем значение текущей ячейки переведённое в строку и записываем его в переменную aStr.

    DataSet.Next;  // переходим на следующую строку
  end;
end.

Обратите внимание: если нужно вывести данные в компонент Таблица, то можно использовать автоматическое заполнение таблицы при помощи метода RunSQL. Например, если в проекте есть таблица с именем Table1, то можно написать такой скрипт:
Код: pascal
var
  aQuery: string;
begin
  aQuery := 'SELECT * FROM `my_table`';  // формируем запрос к БД на выборку всех данных из таблицы `my_table`
  Table1.RunSQL(aQuery, tsAll);          // выполнить запрос и заполнить таблицу результатом выполнения
end.

Не забывайте также, что работать с наборами данных можно только в скриптах с типом "Выполнен SQL-запрос". Информацию о других свойствах набора данных смотрите здесь.

ЦитироватьДинамически, как я прочел, но не пробовал еще, можно добавлять строки.
Да, можно, например так:
Код: pascal
begin
  ComboBox1.AddItem('Моя строка'); 
end.

Цитироватьмогу ли я динамически строку создать и присвоить свойству "Значение", собственно, значение динамически
А вот динамически сменить значение не получится и строка будет принимать значение по-умолчанию равное номеру строки. В будущем постараемся разрешить смену значения.

makimu

#336
Огромное спасибо за оперативный ответ!!!

Ваш код:
Код: pascal
begin
  { выполнять цикл пока не достигнем конца набора данных }
  while not DataSet.EOF do
  begin
    // здесь работаем с текущей строкой
    DataSet.Next;  // переходим на следующую строку
  end;
end.
Делал почти также, но у меня вис сервер, почему также, потому что без DataSet.Next;. Спасибо еще раз за разъяснение данного нюанса =)
З.Ы. Когда выходишь за пределы окна редактирования кода (набрал длинную строку кода), то не появляется полоса горизонтальной прокрутки. Или ее нет?

Simple-Scada

ЦитироватьКогда выходишь за пределы окна редактирования кода (набрал длинную строку кода), то не появляется полоса горизонтальной прокрутки. Или ее нет?
Пока нет, но скоро будет.

deldemo

#338
Здравствуйте Уважаемые.
Последнее время пришлось плотно поработать(не без Вашей помощи) с SQL запросами. В связи с этим есть несколько пожеланий
1. Возможно ли добавить подсветку синтаксиса и сам синтаксис SQL ?
      Если честно, то не очень удобно писать запрос в нынешней реализации S-S. При работе с SQL часто приходится
      переключатся  с ManagementStudio на Simple-Scada и наоборот что неизбежно ведет к ошибкам в синтаксисе.
2. Очень нахватает TAB для выделенных строк
3. При вставке кода из другого редактора , типа Notepad++ , пропадаю TAB-ы

Simple-Scada

ЦитироватьВозможно ли добавить подсветку синтаксиса и сам синтаксис SQL?
Здравствуйте. Для Simple-Scada SQL-запросы это просто текст, который никак не проверяется и не компилируется, а просто передается к БД. Поэтому подсветка SQL-кода не будет добавлена. Но вместо этого возможно добавим выполнение SQL-запросов из файла.

Цитировать2. Очень нахватает TAB для выделенных строк
Для смещения выделенного текста влево/вправо можно использовать комбинации клавиш Ctrl+Sift+U / Ctrl+Sift+I. Либо выполнять смещение через меню "Действия - Увеличить отступ", "Действия - Уменьшить отступ".

ЦитироватьПри вставке кода из другого редактора , типа Notepad++ , пропадаю TAB-ы
Исправим.

bezzub2007

Доброе время суток.
Вопрос. Имеем таблицу с заполненными данными при помощи процедуры RunSQL. Как в скрипте отследить нажатие мышкой на конкретной строке таблицы? Есть ли инструмент отслеживания курсора в таблице?

Simple-Scada

ЦитироватьКак в скрипте отследить нажатие мышкой на конкретной строке таблицы? Есть ли инструмент отслеживания курсора в таблице?
Здравствуйте. Отследить курсор сейчас не получится. Это связано с тем, что на каждом клиенте может быть выбрана разная строка таблицы, а все скрипты выполняются на сервере и он не знает о выделении на клиентах. Но в ближайшем будущем данный вопрос планируется решить и у таблиц появится возможность выделения строк и получения номера выделенной строки.

Миханик

Есть функция GetVariableByName() для обращения к переменной по имени, а есть ли такая же функция для обращения к объектам программы по имени?

Simple-Scada

Цитата: Миханик от 08 июня 2017, 07:58:54а есть ли такая же функция для обращения к объектам программы по имени?
Такой функции нет, с объектами можно работать только обращаясь по имени напрямую.

Teodor

#344
Цитата: Миханик от 08 июня 2017, 07:58:54Есть функция GetVariableByName() для обращения к переменной по имени, а есть ли такая же функция для обращения к объектам программы по имени?
Предложу движняк "через анал" для тех кому оооочень надо. Если вам нужно сменить свойство объекта EditXX:
Делаете пачку переменных VarXX и привязываете к объекту как вторичные. Делаете 2 скрипта. Один меняет по GetVariableByName() значение VarXX, второй привяываете к объекту на изменение вторичной переменной и меняете что хотите сендеру, тоесть объекту EditXX. Значение переменной = состояние объекта, посему в кейсе значения VariableEx задаете все возможные варианты 8)

ИМХО!!!