Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?

Официальный форум Simple-Scada.

Автор Тема: Опять массивы  (Прочитано 2389 раз)

Серега

  • Постоялец
  • ***
  • Сообщений: 249
    • Просмотр профиля
Опять массивы
« : 18 Ноября 2021, 17:21:41 »
Добрый день!
Задача. Есть набор статических данных(меток). Фиксированное положение и не меняется. Объект выдает свое положение. Если находиться рядом с одной из меток зафиксировать сей факт(например увеличить значение переменной на 1).
Идея. Привязать координаты примитива (квадрат) на мнемосхеме к положению объекта (в масштабе) и возле каждой метки отображать сколько раз объект проехал через нее.
Теперь решение. Согласно этой теме https://simple-scada.com/forum/index.php?topic=818.0 можно сделать массив с положением меток.
Так же есть глобальный модуль и в принципе объектов не много, метки одни и те же и можно написать одну глобальную процедуру и использовать ее для всех объектов и будущих.
Проблемы. Создаем массив в глобальном модуле:
Код
interface
var
  array_test: Array[1..3] of Single = (0, 6.8, 10.3)
Пишем процедуру в implementation. Добавляем ее в interface.
Тут вопрос. В interface блок var как то надо заканчивать? Или после переменных можно сразу добавлять определения процедур и функций?
Итак:
Код
procedure proverka(f_array:Array of Single; f_positionTC:TM_Variable; f_dlina_XXX:Single; f_speedTCms:TM_Variable);
Отличие: определяем массив как Array[1..3] of Single, а в процедуре Array of Single. Компиляция проходит.
Вызываем скрипт и ... получаем ошибку о не совпадении типов
'Incompatible types DYNARRAY_Single and ArrayType_1000179'. Понимаю что есть динамический в процедуре и статический в определении массива.
Эксперименты описывать не буду. В глобальном модуле не получилось.
Второй вариант определить локально в скрипте массив.
Определяем массив:
Код
var
  array_test_v1: Array of Single;
Инициализируем:
Код
  array_test_v1[1] := 0.0;
  array_test_v1[2] := 6.8;
  array_test_v1[3] := 10.3;
Вызываем глобальную процедуру:
Код
  proverka(array_test_v1,
            positionTC,
            dlina_430,
            speedTCms);
Компиляция проходит. Но в журнале сервера видим ошибку:
Ошибка в скрипте ... Access violation at address ... Write of address ...
Результат. Пока нету.
Можете проверить у себя. Возможно более подробно осветить тему использования массивов в процедурах и функциях глобального модуля  (но вроде в руководстве не нашел)?
Возможно у Вас есть более простой вариант решения.
Жду вопросов и предложений


Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3156
    • Просмотр профиля
    • Simple-Scada
Re: Опять массивы
« Ответ #1 : 18 Ноября 2021, 17:56:28 »
Здравствуйте.

Работа со статическим массивом. Глобальный модуль:
Код: (delphi)
interface

type
  // объявляем тип статического массива на 3 элемента
  TStaticArray = array[1..3] of single;

var
  // глобальный массив, который будем передавать как параметр
  ArrayAsParam: array[1..3] of single = (0, 6.8, 10.3);


function sum_array(const arr: TStaticArray): single;

implementation

// возвращает сумму элементов массива
function sum_array(const arr: TStaticArray): single;
var
  I: Integer;
begin
  Result := 0;
  for I := Low(arr) to High(arr) do
    Result := Result + arr[i];
end;

end.
Использование. Скрипт нажатия на кнопку:
Код: (delphi)
var
  aRes: Single;
begin
  aRes := sum_array(ArrayAsParam);
  // далее работаем с результатом aRes
end.


Работа с динамическим массивом. Глобальный модуль:
Код: (delphi)
interface

function sum_array_dyn(const arr: array of single): single;

implementation

// возвращает сумму элементов массива
function sum_array_dyn(const arr: array of single): single;
var
  I: Integer;
begin
  Result := 0;
  for I := 0 to Length(arr) do
    Result := Result + arr[i];
end;

end.
Использование. Скрипт нажатия на кнопку:
Код: (delphi)
var
  aRes: Single;
  testArray: array of Single;
begin
  SetLength(testArray, 3);  // выделяем память под три элемента
  testArray[0] := 0;
  testArray[1] := 6.8;
  testArray[2] := 10.3;
  aRes := sum_array_dyn(testArray);
  // далее работаем с результатом aRes
end.
« Изменён: 19 Ноября 2021, 10:34:19 от Simple-Scada »

Серега

  • Постоялец
  • ***
  • Сообщений: 249
    • Просмотр профиля
Re: Опять массивы
« Ответ #2 : 19 Ноября 2021, 10:22:10 »
Добрый день!
Товарищи ну Вы шустрые! +100500 респекта.
Все заработало.
Спасибо!

OlegM

  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
Re: Опять массивы
« Ответ #3 : 12 Марта 2025, 15:47:54 »
Добрый день.
Пытаюсь получить длину массива (тип: универсальный скрипт), но получаю вот такую ошибку
Код
Test | Incompatible types в строке: 5, позиция: 34
Код: (delphi)
var
  anArrayLength: Integer;
  anArray: array [0..10] of Integer;
begin
  anArrayLength := Length(anArray);
end.
Помогите разобраться, пожалуйста!

Кажется, я понял, что функция Length(arr) не поддерживается, и вместо нее нужно использовать High(arr), но как тогда быть с примерами скриптов выше, где эта самая функция Length() используется?
« Изменён: 13 Марта 2025, 10:45:58 от Simple-Scada »

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1301
    • Просмотр профиля
Re: Опять массивы
« Ответ #4 : 13 Марта 2025, 10:42:58 »
Здравствуйте.

Выше рассмотрены два разных примера: работа со статическим массивом и работа с динамическим массивом. У Вас массив статический, поэтому для получения максимального индекса массива нужно использовать функцию "High". Для динамического массива нужно использовать функцию "Length".
Код: (delphi)
var
  anArrayLength: Integer;
  anArray: array[0..10] of Integer;
begin
  // получаем длину статического массива anArray
  anArrayLength := High(anArray) - Low(anArray) + 1;
end.
« Изменён: 13 Марта 2025, 10:53:40 от Simple-Scada »

OlegM

  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
Re: Опять массивы
« Ответ #5 : 13 Марта 2025, 14:01:41 »
Спасибо, теперь понятно. :)