# Array länge mit SCL ermitteln



## Linowitch (22 Oktober 2008)

Hallo,

gibt es in SCL eine Funktion um die länge eines Arrays zu ermitteln?

hab leider nichts dazu gefunden.

Danke.


----------



## Larry Laffer (22 Oktober 2008)

Nein ... 
was hast du denn vor ...?


----------



## Linowitch (22 Oktober 2008)

Ich will ein Array durchlaufen und die Werte auswerten,
nur sind die Arrays nicht immer gleich lang und um mir einen zusätlichen Parameter, der die länge angibt, zu ersparen, wollte ich die mit SCL selbst ermitteln.

Da komm ich wohl um den Parameter nicht rum. Schade

Danke


----------



## Larry Laffer (22 Oktober 2008)

... vielleicht ist das ja was für dich :
Ich definiere bei manchen meiner Routine im Kopf Konstanten. Diese Konstanten kannst du auch für die Array-Dimensionierung hernehmen bzw. als End-Variable bei einer Schleife ...

Gruß
LL


----------



## Grubba (22 Oktober 2008)

Wenn Du den Array als Any-Parameter an eine Funktion übergibst, kannst Du aus dem Any-Pointer den Wiederholfaktor auslesen. Das ist dann die Länge Deines Arrays. In AWL ist das so ohne weiteres möglich, diese AWL Funktion könntest Du dann in SCL aufrufen und dir als Rückgabewert der Funktion die Länge zurückgeben lassen.


EDIT:

Habe gerade mal ein wenig rumgespielt und beobachtet, das bei *symbolischer* Übergabe eines Arrays im AnyPointer der Typ immer als Byte, und als Wiederholfaktor immer die Länge des Arrays in Byte steht.

Bei Definition Deines Array direkt im SCL-Code funktionierts aber.


```
FUNCTION FC51 : INT
 
VAR_TEMP
  MyArray       : ARRAY[1..17] OF WORD; //Dein Arr eines beliebigen Typs 
  PAny           : ANY;
  ATVar AT PAny : ARRAY[1..5]  OF WORD;
END_VAR
PAny := Myarray;
// Zuweisungen zum Beobachten
ATVar[1] := ATVar[1]; 
ATVar[2] := ATVar[2]; // Hier steht die Länge Deines Arrays 
ATVar[3] := ATVar[3];
ATVar[4] := ATVar[4];
ATVar[5] := ATVar[5];

FC51 := 51;
END_FUNCTION
```


----------



## Larry Laffer (22 Oktober 2008)

@Grubba:
Diese Möglichkeit hatte ich gar nicht bedacht ...
Das geht natürlich auch in SCL (und sogar sehr schön) zu machen. Die Frage ist natürlich, da die ARRAY's ja nicht dynamisch deklariert werden können, ob das so Sinn macht ...

Gruß
LL


----------



## Grubba (22 Oktober 2008)

Hi Larry, 

hab gerade nochmal editiert. Ist so, dass bei Übergabe eines Arrays als
Any

-> InputAny := TestArray

als Typ immer Byte (2) ausgegeben wird, Wiederholfaktor ist dann immer die Anzahl der Bytes.

mit z.B.

-> InputAny := P#DB1234. dbx0.0 Real 123 

wird dann auch korrekt der wiederholfaktor 123 angegeben. 

Du noch Ideen, wie mans auch symbolisch hinkriegt ?


----------



## Larry Laffer (22 Oktober 2008)

Grubba schrieb:


> Du noch Ideen, wie mans auch symbolisch hinkriegt ?


 
Wenn dein DB sysbolisch deklariert ist und du in dem DB den Bereich als ARRAY of REAL (dein Beispiel) deklariert hast (mit der gleichen Größe), dann sollte die symbolische Zuordnung übernommen werden ... oder anders herum kannst du sie dort hin schreiben ...

Gruß
LL


----------



## Grubba (22 Oktober 2008)

Genau das ist das Problem.

Angenommen, Du deklarierst in zwei DBs zwei identische Arrays. (Z.B. Array of Real) Den einen übergibst Du symbolisch, den anderen direkt. Der symbolische wird von Step 7 wohl automatisch so umformatiert, das der Datentyp immer vom Typ BYTE ist, und der Wiederholungsfaktor der Anzahl der Bytes entspricht.
Wird er direkt adressiert, ist der Datentyp dann vom Typ Real, und der Wiederholungsfaktor entspricht der Anzahl der Elemente (Und nicht der Bytes).
Aus irgendeinem Grund geht Step7 wohl hin und formatiert bei symbolischer Adressierung intern auf Byte um.

Mein Interesse ist hier nur theoretischer Natur, würde mich halt mal interessieren warum das so ist.


----------



## hammerheadbene (26 Mai 2010)

Hat super funktioniert, zumindest für den Sinn und Zweck, wofür ich es benötige.


----------



## Onkel Dagobert (26 Mai 2010)

Grubba schrieb:


> ...Aus irgendeinem Grund geht Step7 wohl hin und formatiert bei symbolischer Adressierung intern auf Byte um.
> 
> Mein Interesse ist hier nur theoretischer Natur, würde mich halt mal interessieren warum das so ist.



Ich vermute, es ist ganz einfach mal so fest gelegt worden. Der Compiler generiert in den Fällen der sympolischen Programmierung immer einen Pointer mit dem Datentyp Byte. Verständlicher wird es, wenn man bedenkt dass der symbolische ANY z.Bsp. auch auf ein STRUCT zeigen kann. Man kann den Datentyp in SCL und AWL allerdings auch auslesen und bei der Längenermittlung berücksichtigen. Ich prüfe meist nur, ob der Datentyp vom Typ Byte ist. Ist er es nicht, breche ich die Bearbeitung ab und gebe einen Fehlercode aus.


Gruß, Onkel


----------



## oldman (8 Juli 2010)

*Array-Indexe als Variable ?*

Hallo zusammen,
wenn man die Array-Indexe (insbesondere den Ende-Index) als Variable benötigt, so geht dies nur über Konstante:


```
CONST
  BufStart   :=  1;      // Start-Index
  BufEnd     :=  100;   // End-Index
END_CONST

VAR
  N : INT;                 // Loop-Variable (FOR - NEXT)
END_VAR
```
Die Deklaration sieht dann so aus:

```
VAR
  // static Variables
  // replace for: Buffer  :   ARRAY[1..100] OF WORD;
  Buffer  :   ARRAY[BufStart..BufEnd] OF WORD;
END_VAR
```
So kann man dann z.B. in einer For - Next - Schleife direkt mit den Konstanten arbeiten:

```
BEGIN
  // Commands
  .
  .
  // erase buffer
  FOR N := BufStart TO BufEnd DO
    Buffer[N]   :=  0;
  END_FOR;
  .
  .
```
So kann man direkt die Array-Elemente (in diesem Fall WORD) behandeln
und muss nicht über BYTE-Umrechnungen gehen.

Ich hoffe, das das zu Eurem Problem passt.

Gruss, Oldman


----------



## KarlosMüller (20 Oktober 2022)

Hallo, 
wollte mal fragen, ob es mittlerweile in SCL eine Funktion gibt die Arraylänge, wie Beispielsweise bei C# einfach abzufragen. 
Also z.B. über arrayXY.length
Mein genaues Problem:
Wenn ich Störmeldungen anlege kann es ja immer sein, dass da noch welche hinzu kommen. Wenn ich aber eine For-Schleife über die Störungen laufen lasse muss ich beim Hinzufügen ja immer auch den Parameter anpassen, wie weit die Schleife laufen soll. Hier hätte ich gerne einfach 
FOR #i := 1 TO #ArrayXY.length DO
     code
end_for

Grüße, 

K.


----------



## MFreiberger (20 Oktober 2022)

Moin KarlosMüller,

wenn das Array als Variant vorliegt:
CountOfElement();
==> hier vielleicht vorher noch prüfen, ob ein Array vorliegt: IS_ARRAY();

wenn das Array als Array vorliegt:
UPPER_BOUND() - LOWER_BOUND();

VG

MFreiberger


----------



## MFreiberger (20 Oktober 2022)

Wenn ich ein Array definiere, starte ich gerne bei 0.
Für den maximalen Index lege ich dann unter PLC-Variablen eine Konstante an.
(Ggf. für den minimalen Index auch)

Also:
ARRAY[0.."maxIndex"] of byte
ARRAY["minIndex".."maxIndex"] of byte

Dann die Schleife:

```
FOR i := 0 TO maxIndex DO
    <something>;
END_FOR;
```

Dann brauche ich nur den maxIndex anpassen und Array und Schleife passen zusammen!

VG

MFreiberger


----------



## Olli_BS (20 Oktober 2022)

Sonst für sowas Anwenderkonstante definieren und beim definieren des Arrays die Konstante statt einer Zahl eingegeben. (Bei den Schleifen-Max natürlich auch!)  Dann arbeiten alle immer mit dem selben Wert.


----------



## Watchcat (20 Oktober 2022)

Hallo, in TIA V16 mit ner 1500er ist dies auf jeden Fall möglich (bisher nur in der Konstellation genutzt),
Dazu muss das Array über ein IN-Parameter mit dem Datentyp Array[*] an einen Baustein übergeben werden.




Gruß Jonas


----------



## Wincctia (20 Oktober 2022)

Hallo 

falls du Tia verwendest kannst du dir einen FC mit einmei Variantvals Eingang Anlegen und darin nach IS Array fragen und dann Count of Elementes so kann die Zahl der Elemente gelesen werden. Finde dieses Konstrukt erlich gesagt nicht wirklich gut.

Gruß Tia


----------



## KarlosMüller (25 Oktober 2022)

Servus Leute, 

also vielen Dank für eure vielen guten und kreativen Ideen. Das bedeutet also, dass es keine Funktion gibt mit array.length die Länge abzufragen?! 
Schade eigentlich -.- 
Aber ok, dann muss ich wohl einen der anderen Wege ausprobieren ;-)


----------



## escride1 (25 Oktober 2022)

KarlosMüller schrieb:


> Das bedeutet also, dass es keine Funktion gibt mit array.length die Länge abzufragen?!





MFreiberger schrieb:


> wenn das Array als Variant vorliegt:
> CountOfElement();
> ==> hier vielleicht vorher noch prüfen, ob ein Array vorliegt: IS_ARRAY();
> 
> ...


Ja doch?


----------

