Jump to content

mehrere Einträge aus einer Liste abrufen


fzonk

Recommended Posts

Hallo an Alle,

ich stehe gerade etwas auf dem Schlauch und habe gleich mal ein Beispiel angehangen. Ich habe in dem Kippschalter eine Liste erstellt mit den 5 Lampen (die Schalter sind). Nun würde ich gern mehrere Objekte aus dieser Liste gleichzeitig ansprechen (Lampen umschalten), dabei möchte ich aber in der EV nicht für jede Lampe eine Aktion erstellen. Gibt es die Möglichkeit über eine Aktion mehrere Objekte gleichzeitig aus der Liste anzusprechen. Als Beispiel ich hätte gern das Lampe 1; 3 und 5 um geschalten werden.

Gruß Frank

Liste abrufen.mbp

Link to comment
Share on other sites

Hallo Frank,

hier ist zunächst eine Version in der alle (und nicht nur ausgesuchte) Elemente der Liste angesprochen werden.
Sie kommt außerdem ohne eine Bedingung aus, weil einfach die Schalterstellung an die 5 Lampen übertragen wird.

Damit hast du schon zwei Dinge hinzugelernt. Den Einsatz von Wiederholungen und eine Alternative zur Bedingung.

Um jetzt gezielt nur einen Teil der Liste anzusprechen, müsstest du diesen Teil irgendwie vom Rest unterscheiden. Und da wäre es doch das einfachste, dass du nur diesen Teil in die Liste packst. Alternativ kannst du es natürlich auch mit einem Schlagwort in manchen Objekten hinkriegen oder anhand des Namens und per Lua ausbaldowern, wer nun umschalten darf und wer nicht.

Aber warum willst du dir das Leben schwerer machen als nötig?

Demo-Anlage:  Liste abrufen (alle).mbp

Link to comment
Share on other sites

Hallo Götz,

erst einmal vielen Dank für deine Mühe. Dass mit der Wiederholung für alle hinterlegten Objekte kannte ich schon. Ich hatte gehofft es gibt die Möglichkeit über eine Aufzählung nur bestimmte Bestandteile anzusprechen.

Gruß Frank

Link to comment
Share on other sites

vor 4 Stunden schrieb Tesla:

sehe ich das richtig ...?

Nein, das siehst du falsch. Pardon. Ich hatte fälschlich Ereignisverwaltung gelesen und nicht Ereignisprotokollierung

Die Liste bearbeitest du (wie eine Variable) dort, wo sie steht. Im Fall von Franks Beispiel steht sie im Kippschalter.
Es gibt mehrere Wege zu dieser Liste.

  • Das Ereignisprotokoll ist einer davon (wenn dort in der rechten Spalte das Objekt steht)
  • Ein Rechtsklick auf das Objekt mit anschließendem "Schlagwort/Variable bearbeiten" ist ein zweiter.
  • Ein Klick auf das Symbol mit den drei waagerechten Strichen im Eigenschaftsfenster ist ein dritter.
  • ...
Edited by Goetz
Aussage korrigiert
Link to comment
Share on other sites

Hallo Frank,
dein Posting hatte ich leider durch das nachfolgende von Tesla übersehen. Sorry!

vor 3 Stunden schrieb fzonk:

Ich hatte gehofft es gibt die Möglichkeit über eine Aufzählung nur bestimmte Bestandteile anzusprechen.

Ja, die gibt es.
Leg nur bestimmte Bestandteile in die Liste. (Das wäre der einfachste Weg)

Die Frage ist:
Wie möchtest du unterscheiden, welche Dinge aus der Liste verwendet werden sollen und welche nicht? Du willst nicht alle einzeln ansprechen. Okay. Aber dann musst du doch auf andere Weise festlegen, welche Elemente betroffen sein sollen. Sag du mir, woran die Elemente erkennbar sind und ich sage dir, wie du sie in der Wiederholung identifizierst.

  • Wenn sie z.B. ein bestimmtes Schlagwort haben, dann kann ich dir zeigen, wie du diese Elemente in der Wiederholung rausfilterst.
  • Wenn es der Name ist, dann kann ich dir zeigen, wie du den (mittels Lua) zerlegst und nach einem bestimmten Namensteil suchst.
  • Wenn es der Index in der Liste ist, dann zeige ich dir, wie du eine zweite Liste mit den Indexen erstellst und auf die erste anwendest.

Zur dritten Version (die deiner Eingangsfrage am nächsten kommt) habe ich hier eine weitere Demoanlage für dich:
Liste abrufen (Auswahl).mbp

Edited by Goetz
Beispielanlage hinzugefügt
Link to comment
Share on other sites

Hallo @Goetz

Ja es geht um die Variante 3, ich möchte Teile des Indexes aufrufen. Dein Beispiel kommt meiner Vorstellung schon sehr nah. Ich hatte mir eine noch einfachere Lösung gewünscht. In der Grafischen EV in etwa so:

Bild.jpg.91b1d45a390d8ad24922469171ced937.jpg

Oder in Lua eventuell so:

$("Kippschalter").variables["Lampen"]["1"]["3"]["5"].state = state 

Aber scheinbar gibt es da keine so einfache Lösung, oder doch?

Gruß Frank

Nachtrag:

Ich hatte auch noch die Idee zu dieser Lösung:

$("Kippschalter").variables["Lampen"]["1"and"3"and"5"].state = state   

interessanter weiße verarbeitet Lua den Befehl sogar ohne Fehlermeldung, aber leider wird nur die Lampe 5 geschalten. Wenn ich die „and“ gegen „or“ austausche wird nur die erste Lampe geschalten. Aber ist halt noch immer nicht die Lösung die ich anstrebe.

Edited by fzonk
Link to comment
Share on other sites

vor einer Stunde schrieb fzonk:

interessanter weiße verarbeitet Lua den Befehl sogar ohne Fehlermeldung

Gar nicht interessanterweise, sondern völlig normal. Lua interpretiert 1 AND 3 AND 5 als logische Operation mit dem Ergebnis 5 und schaltet daraufhin korrekt die Lampe mit Index 5. Die logische Operation 1 OR 3 OR 5 ergibt 1 und auch da wird völlig korrekt Lampe 1 geschaltet.

Gruß Timba

Link to comment
Share on other sites

Hallo Timba,

vor 15 Minuten schrieb Timba:

Gar nicht interessanterweise, sondern völlig normal. Lua interpretiert 1 AND 3 AND 5 als logische Operation mit dem Ergebnis 5 und schaltet daraufhin korrekt die Lampe mit Index 5. Die logische Operation 1 OR 3 OR 5 ergibt 1 und auch da wird völlig korrekt Lampe 1 geschaltet.

Für mich schon, weil ich mich an Lua gerade erst herantaste o.O

Das Beispiel mit den Lampen ist gerade nur stellvertretend für eine andere Funktion an der ich gerade bastle. Bei dieser sind es 32 Objekte. In verschieden Aktionen will ich teilweise alle auf einmal ansprechen, was über Wiederholung kein Problem ist, zum Teil will ich aber auch nur einige bestimmte Objekte davon ansprechen, die Zusammenstellungen der Objekte ändert sich dabei immer wieder. Nun suche ich einen einfachen Weg wie ich bestimmte Objekte aus einer Liste ansprechen kann. 

 

Gruß Frank

Link to comment
Share on other sites

Hallo Frank,

mit Lua kannst du es so schreiben:

for i, Wdh in ipairs({1, 3, 5}) do
  $("Kippschalter").variables["Lampen"][Wdh].state = state
end

ipairs nimmt Wertepaare aus einer Tabelle und weist sie den beiden Variablen links vom in zu.
Traditionell heißen diese Variablen k und v für key (Schlüssel, also der Name der Zelle) und value (Wert, also der Zelleninhalt).

Das MBS nennt die Variablen i (für Index) und Wdh (für Wiederholung), wenn man eine grafische EV umwandelt.
Und im konkreten Beispiel spielt der Index i anschließend keine Rolle.

Als Funktionsargument übergibt man an ipairs eine Tabelle. Meistens den Tabellennamen. Aber man kann auch direkt die Tabelle einfügen. Die runden Klammern gehören also zu ipairs und kennzeichnen das Funktionsargument. Die geschweiften Klammern darin deklarieren die Aufzählung als Tabelle.

for ... in bewirkt, dass der Reihe nach alle Wertepaare aus der Tabelle ausgelesen und an die Variablen übergeben werden.

Demo-Anlage:   Liste abrufen (Lua).mbp

 

Viele Grüße
Götz

__________________________________________________________________________

 

Nachtrag zu and und or:

Timba hat es schon angedeutet: Bei and bekommst du nur den letzten, bei or den ersten Wert zurück, weil beides logische Operatoren sind. Sie haben nichts mit Aufzählungen zu tun.

Gedacht sind sie für Konstrukte wie

if Bedingung_1 == 17 and Bedingung_2 == 4 then

Der Vergleich mit == liefert ein true (wahr) oder false (falsch) zurück. Und genau das benötigt if für seine Entscheidung, entweder true oder false.

Bei and müssen alle Bedingungen erfüllt sein. Und das bedeutet: Wenn die erste Bedingung nicht erfüllt ist, dann hat sich die Sache schon erledigt. Ist das erste Ergebnis false, dann bekommt das if ein false und der Rest wird nicht mehr geprüft. Eventuelle Funktionen in den nachfolgenden Bedingungen werden nicht ausgeführt!

Dasselbe gilt für alle weiteren verknüpften Verbindungen: Sobald eine Bedingung nicht erfüllt ist, bekommt das if ein false gemeldet und die Prüfung wird abgebrochen.

Sind alle Bedingungen bis auf die letzte erfüllt gewesen, dann gibt Lua das Ergebnis des letzten Vergleichs ungeprüft an das if weiter. Denn jetzt hängt alles alleine von dieser Bedingung ab. Sie enthält also jetzt in jedem Fall das, was das if bekommen muss.

 

Beim or kehren sich die Verhältnisse um, aber das Prinzip bleibt dasselbe. Diesmal reicht ja eine einzelne erfüllte Bedingung. Also wird das erste wahre Resultat direkt an das if weitergegeben. Und wenn alle vorherigen Bedingungen nicht erfüllt waren, dann gibt Lua die letzte Bedingung ungeprüft an das if weiter, denn sie enthält jetzt die richtige Antwort.

 

Der Empfänger dieser boolschen Verknüpfungen muss nicht zwingend die if-Verzweigung sein.
Man kann das Ergebnis ebenso gut an eine Variable übergeben.

v = Bedingung > 42 or Bedingung < 1

Die einzelnen Operanden müssen nicht zwingend Vergleiche sein.
Jede Zahl und jeder String haben in Lua den boolschen Wert true. Auch die Zahl 0 und der leere String ""
Ein fehlender Wert wird in Lua durch nil repräsentiert und als false gewertet.

Das erlaubt Tricks wie diesen hier

a = (a or 0) + 1

Wenn a existiert, dann ist der Wert links vom or true und wird verwendet.
Existiert a (noch) nicht, dann wird es durch die 0 rechts vom or ersetzt.

 

Aus diesen Erläuterungen kannst du ableiten, warum du bei and (nur) den ersten und bei or (nur) den letzten Wert bekommst.
 

Edited by Goetz
ergänzende Erklärungen
Link to comment
Share on other sites

vor 2 Stunden schrieb Andy:

Bliebe vielleicht noch zu erwähnen, dass Stringoperationen naturgemäß zu den langsamsten überhaupt gehören

Moin,

will der Nutzer weniger tun, muss die Maschine halt mehr tun. ;) Frank hatte oben den (mit Bild) Wunsch geäußert, nur ein paar Zahlen mit Trennzeichen in eine Variable setzen zu können. Da Lua eine solche Eingabe nicht als eine Auflistung mehrerer Zahlen interpretieren kann kam mir die Idee, einen String auszuwerten. Das mag nicht so "professionell" sein (bin ja auch kein Professioneller), aber es erreicht eben das gewünschte Ziel.

 

Link to comment
Share on other sites

vor 3 Stunden schrieb Goetz:

Nachtrag zu and und or

Hallo Götz,

gut aufgeklärt. Gestern hatte ich nur gesehen, dass Lua das so auswertet, konnte mir aber nicht erklären, warum. Meine Überlegung war, wenn 1 true ist und 3 true ist, dann muss eine logische Operation »1 and 3« ebenfalls einfach true sein, weil »true and true« eben true ist. Außer bei einem bitweisen Vergleich, aber dann hätte »1 and 3 and 5« nicht 5 sein können, sondern 1. Und »1 or 3 or 5« hätte sogar 7 sein müssen. Also schied ein bitweiser Vergleich aus und es war klar, dass die Zahlen verglichen werden. Nun weiß ich, warum in einem Fall die erste und im anderen Fall die letzte Zahl genommen wurde.

Gruß Timba

Link to comment
Share on other sites

Hallo an Alle,

ich bedanke mich für die super Vorschläge, und die Lösung die ich gesucht habe ist diese von @Goetz:

for i, Wdh in ipairs({1, 3, 5}) do
  $("Kippschalter").variables["Lampen"][Wdh].state = state
end

Bei dieser ist genau dies was ich gesucht habe perfekt (y) Genau das richtige für „Faule“, ich brauch einfach nur die Indexzahlen eintragen, die ich ansprechen will und fertig ist.

Danke euch allen, Frank

P.S.: ich fange gerade erst an mich langsam mit Lua anzufreunden, leider sind meine Grundkenntnisse nahezu Null, das letzte Mal wo ich mich mit sowas beschäftigt habe ist weit über 20 Jahre her und da hieß das Ganze noch Basic…

Edited by fzonk
Link to comment
Share on other sites

Hallo,

... ich weiß, es ist sehr speziell, aber in Lua gibt es einen mächtigen "Stringzerleger" "string.gsub" mit dem man (unter anderem) strings mit  Trennzeichen in eine Tabelle umwandeln kann...
 

t={}
str="10;5;9"
str:gsub("(%d+)",function(c) table.insert(t,c) end)

for i,v in ipairs(t) do
print(i,v)
end

-- Ergebnis:
1	10
2	5
3	9

wobei das Trennzeichen in diesem Fall nur darauf beschränkt ist, dass es keine Ziffer (%d) sein darf (das "+" bedeutet, dass zusammenhängende Ziffern berücksichtigt werden)

t={}
str="10.5 9:7a4"
str:gsub("(%d+)",function(c) table.insert(t,c) end)

for i,v in ipairs(t) do
print(i,v)
end

--Ergebnis:
1	10
2	5
3	9
4	7
5	4

... wenn ich das Beispiel von Andy nehme, dann würde es dann so aussehen, wenn der Schalter betätigt wird... (alles umgewandelt in Lua)
 

if controller.state == 1 then
  local  t={}
  local str=$("Ereignisse").variables["Lampenschaltung"] -- Lampenauswahl (Index von "Lampen" mit Trennzeichen)
  str:gsub("(%d+)",function(c) table.insert(t,c) end)    --String in Tabelle umwandeln
  for i,v in ipairs(t) do                                -- Lampen einschalten
     $("Ereignisse").variables ["Lampen"][v].state = 1
   end
else
  local t = $("Ereignisse").variables["Lampen"] -- alle Lampen aus
  for i, Wdh in ipairs(t) do
    Wdh.state = 0
  end
end

und die Variable "Lampenschaltung" hat dann beispielsweise diesen Eintrag "1;4;5;7;12"

Timba's Lampenladen mit Aufzählung-1.mbp

Gruß
EASY

 

 

Link to comment
Share on other sites

Hallo @EASY,
wenn man's unbedingt mit String machen will, ist es gut die Funktion mal kennenzulernen. Zerlegt direkter als bei Timba.
Aber die variablen Argumente gefallen mir trotzdem besser. Klar, die muß man dann diskret angeben. Da ist dann wieder nix mit Variable.

@fzonk, Du schreibst, Du mußt es öfters mit einer unbekannten Anzahl ausführen und schreibst die Zahlen auch direkt rein. Bei Deinem Favoriten brauchst Du da immer drei Zeilen dann, ich nur eine (siehe Lampenladen mit Aufzählung) plus einmal die Funktion im Skript.

Gruß
  Andy

Link to comment
Share on other sites

Hallo Andy,

vor 10 Minuten schrieb Andy:

wenn man's unbedingt mit String machen will, ist es gut die Funktion mal kennenzulernen

... genau so war es auch angedacht... Lua bietet unterschiedliche Möglichkeiten ein Problem zu lösen...

Gruß
EASY

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...